0

We are using Spring and we used Spring AOP. Due to the nature of Spring AOP which uses Proxy we reached the limitation of it when tring to warp join point on call inside a call. i.e aspect on B execution will not run if A is being call

public void A(){
   B()
}
public void B(){
}

In order to solves this issue we are using ApsectJ weaven in compile time.

Which is work good. But then, the issue is make it play nice with Spring Bean i.e let the Autowired work in side the aspect class.

Pom.xml Maven plugin

        <!-- AspectJ configuration -->
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.7</version>
            <configuration>
                <complianceLevel>1.8</complianceLevel>
                <source>1.8</source>
                <target>1.8</target>
                <showWeaveInfo>true</showWeaveInfo>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

EDIT

duplicate of Spring autowired bean for @Aspect aspect is null

info on how to get aspectj to work with maven

Community
  • 1
  • 1
oak
  • 2,898
  • 2
  • 32
  • 65

1 Answers1

0

Use AspectJ in compile time and make sure spring autowired magic will work

According to the AspectJ doc aspectOf Chapter. In order to some module to known that aspect is an aspect of something one should use aspectOf. Spring has the feature

 <bean id="a" class="com.someinterface.A" factory-method="aspectOf"></bean>

This will result the A of above to be a Spring Bean and as a bonus Spring will know that this is an aspect of some other code. This is enough for Spring to use the Autowire magic inside of an aspect.

NOTE that using aspectOf requires xml configuration. I tried to get the same result with @Configurable but it did not work. if some one has some info on that it will great. :)

Bonus - Use Spring AOP proxy for aspect(in run time)

Set spring to scan @Aspect and make it a spring bean

<context:component-scan base-package="com.centure" >
     <context:include-filter type="annotation"     expression="org.aspectj.lang.annotation.Aspect"/> 
</context:component-scan>

in this case every thing will work out of the box

private SomeService service;
public SomeService getService() {
    return service;
}

@Autowired
public void setService(SomeService) {
    this.service = service;
}
@Aspect
public class myAspect {
    @Pointcut("execution(public * com.myinterface.save(..))")
         public void save() {
    }

@Around("myAspect () && args(thearg)")
public Object doBasicProfiling(ProceedingJoinPoint pjp, TheObject thearg)
         throws Throwable {

    Object retVal = null;
    try {
        retVal = pjp.proceed();
    } catch (Throwable e) {
        e.printStackTrace();
    }

    return retVal;
    }
oak
  • 2,898
  • 2
  • 32
  • 65