12
votes

I have created two Spring AOP pointcuts that are completely separate and will be woven in for different parts of the system. The pointcuts are used in two different around advices, these around-advices will point to the same Java method.

How the xml file looks:

<aop:config>
    <aop:pointcut expression="execution(......)" id="pointcutOne" />
    <aop:pointcut expression="execution(.....)" id="pointcurTwo" />

    <aop:aspect id="..." ref="springBean">
        <aop:around pointcut-ref="pointcutOne" method="commonMethod" />
        <aop:around pointcut-ref="pointcutTwo" method="commonMethod" />
    </aop:aspect>
</aop:config>

The problem is that only the last pointcut works (if I change the order pointcutOne works because it is the last one). I have gotten it to work by creating one big pointcut, but I would like to have them separate. Any suggestions to why only one of the pointcuts works at a time?

1
I guess aop:aroung is a typo in the question only.Bozho

1 Answers

8
votes

Try to have the pointcut and advice inside the <aop:aspect> element. Something like this:

<aop:config>
  <aop:aspect id="aspect1" ref="springBean">
    <aop:pointcut expression="execution(......)" id="pointcutOne" />
    <aop:around pointcut-ref="pointcutOne" method="commonMethod" />
  </aop:aspect>

  <aop:aspect id="aspect2" ref="springBean">
    <aop:pointcut expression="execution(.....)" id="pointcurTwo" />
    <aop:around pointcut-ref="pointcutTwo" method="commonMethod" />
  </aop:aspect>
</aop:config>

I guess your XML configuration resulted in just one proxy object, while it should have been two proxy objects.


Btw: You should consider using @AspectJ syntax instead. It's just Java with pointcuts and advices in annotations. It works well with Spring AOP and offers more functionality than the XML alternative.

All you need in your configuration to enable @AspectJ aspects with Spring AOP:

<aop:aspectj-autoproxy>
     <aop:include name="aspect1" />
     <aop:include name="aspect2" />
</aop:aspectj-autoproxy>

<bean id="aspect1" class="com.demo.Aspect1"/>
<bean id="aspect2" class="com.demo.Aspect2"/>

And the Aspect could be something like this:

@Aspect
public class Aspect1 {

    @Pointcut("execution(* *(..))")
    public void demoPointcut() {}

    @Around("demoPointcut()")
    public void demoAdvice(JoinPoint joinPoint) {}
}

Updated:

Example that uses a pointcut to combine three other pointcuts:

@Pointcut("traceMethodsInDemoPackage() && notInTestClass() " +
    "&& notSetMethodsInTraceDemoPackage()")
public void filteredTraceMethodsInDemoPackage() {}