I am currently developing two Spring applications that makes use of Spring-AOP. I have an aspect that allows simple performance logging which is defined as such:
@Aspect
final class PerformanceAdvice {
private Logger logger = LoggerFactory.getLogger("perfLogger");
public Object log(final ProceedingJoinPoint call) throws Throwable {
logger.info("Logging statistics.");
}
}
This advice can then be created through Spring AOP configuration with the following XML:
<bean id="performanceAdvice" class="com.acme.PerformanceAdvice" />
<aop:config>
<aop:aspect ref="performanceAdvice">
<aop:around pointcut="execution(* com.acme..*(..))" method="log"/>
</aop:aspect>
</aop:config>
This works fine for classes that are created by Spring such as classes annotated with @Service. But I'd like this aspect to also advise other aspects in the secondary project. I'm aware Spring doesn't support this as noted in their docs:
In Spring AOP, it is not possible to have aspects themselves be the target of advice from other aspects. The @Aspect annotation on a class marks it as an aspect, and hence excludes it from auto-proxying.
Thus I'm probably in need of something more powerful such as AspectJ. Or is it possible to make Spring aware of the aspect and still allow advising? From numerous other questions (that aren't directly related to this specific problem) on StackOverflow I have tried making aspects @Configurable, making them Spring-aware by defining them as a @Component and played around with various XML and plugin settings such as:
<context:spring-configured />
<context:annotation-config/>
<context:load-time-weaver/>
<aop:aspectj-autoproxy/>
I'm running out of ideas now. Will I be needing to write fully-fledged AspectJ aspects? If so, can it use the same configuration such as Spring, referencing the existing aspect and defining a new pointcut? This would be useful so I don't have to re-work the PerformanceAdvice for Project 1 but still reference and use it in Project 2.
edit regarding this comment: To make myself more clear, I have the following example.
I have a Service in Project 2.
@Service
public class TargetSpringServiceImpl implements TargetSpringService {
@Override
public String doSomeComplexThings(String parameter) {
return "Complex stuff";
}
}
When this method gets called, I have an aspect that does some validation.
@Aspect
public class ValidationAdvice {
@Autowired
ValidationService validationService
public void validate(JoinPoint jp) throws Throwable {
//Calls the validationService to validate the parameters
}
}
With the following pointcut as execution:
<bean id="validationAdvice" class="com.acme.advice.ValidationAdvice" />
<aop:config>
<aop:aspect ref="validationAdvice">
<aop:before pointcut="execution(* com.acme.service..*(..))" method="validate"/>
</aop:aspect>
</aop:config>
I'd like to have my PerformanceAdvice's log() method to be invoked on the ValidationAdvice's validate() method. NOT on the doSomeComplexThings() method of the TargetSpringService class. As this is just an additional pointcut. The problem lies with advising the method of another aspect.