Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why is this Spring AOP pointcut not triggered?

Tags:

java

spring

aop

I'm writing very basic schema-based Spring AOP, here's the .xml

<bean id="aoplistener" class="tao.zhang.Listener"/>

<aop:config>
  <aop:aspect ref="aoplistener">                
    <aop:pointcut id="whenCalled" expression="execution(* callme(..))" />
    <aop:after method="scream" pointcut-ref="whenCalled" /> 
  </aop:aspect>
</aop:config>

The method scream() in tao.zhang.Listener just prints out some text, and is supposed to be executed whenever a method callme() is called.

I have a bean called logger which has the methods log() and callme()

public void log(){
    callme();
    System.out.println("Hello from logger ~~~~~~~~~~~~~~~~~~~");
}

public void callme(){
    System.out.println("I'm called");
}

Note that callme() is called by log()

Now I have a scheduler which calls log() every 5 seconds:

<task:scheduler id="myScheduler" pool-size="10"/>

<task:scheduled-tasks scheduler="myScheduler">
    <task:scheduled ref="logger" method="log" fixed-rate="5000"/>
</task:scheduled-tasks>

Strangely, scream() is not invoked, but if callme() is called directly:

<task:scheduler id="myScheduler" pool-size="10"/>

<task:scheduled-tasks scheduler="myScheduler">
    <task:scheduled ref="logger" method="callme" fixed-rate="5000"/>
</task:scheduled-tasks>

scream() is invoked!

Any suggestions? It seems to me that this pointcut doesn't match methods called inside another method ...

like image 530
Tao Avatar asked Feb 10 '12 05:02

Tao


People also ask

What is PointCut in Spring AOP?

In Spring AOP, a join point always represents a method execution. A pointcut is a predicate that matches the join points, and the pointcut expression language is a way of describing pointcuts programmatically.

How do I enable AOP in spring?

For using Spring AOP in Spring beans, we need to do the following: Declare AOP namespace like xmlns:aop=“https://www.springframework.org/schema/aop” Add aop:aspectj-autoproxy element to enable Spring AspectJ support with auto proxy at runtime. Configure Aspect classes as other Spring beans.

What is PointCut in AspectJ?

AspectJ provides primitive pointcuts that capture join points at these times. These pointcuts use the dynamic types of their objects to pick out join points. They may also be used to expose the objects used for discrimination. this(Type or Id) target(Type or Id)


1 Answers

Spring AOP only traps a method call when the call is done through a bean handle (because the interceptor is applied through the use of a proxy object) and not when the method is called directly.

To make your code work, you need to either switch to using AspectJ (which works by rewriting the class's bytecode, which allows it to intercept far more things and to do so more transparently) or to change how you call callme() so that it is via a bean handle:

SomeClass selfRef;

public void log(){
    selfRef.callme();
    System.out.println("Hello from logger ~~~~~~~~~~~~~~~~~~~");
}

public void callme(){
    System.out.println("I'm called");
}

You need to configure the selfRef field explicitly; it won't be autowired.

like image 88
Donal Fellows Avatar answered Nov 14 '22 23:11

Donal Fellows