I have the following spring configuration:
<context:component-scan base-package="uk.co.mysite.googlecontactsync.aop"/>
<bean name="simpleEmailSender" class="uk.co.mysite.util.email.simple.SimpleEmailSenderImplementation"/>
<aop:aspectj-autoproxy/>
Then I have an aspect:
@Aspect
public class SyncLoggingAspect {
@Autowired
private SimpleEmailSender simpleEmailSender
@AfterReturning(value="execution(* uk.co.mysite.datasync.polling.Poller+.doPoll())", returning="pusher")
public void afterPoll(Pusher pusher) {
simpleEmailSender.send(new PusherEmail(pusher));
}
}
This aspect works (I can hit a breakpoint on afterPoll) but simpleEmailSender is null. Unfortunately I cannot find clear documentation on why this is. (For the record, my simpleEmailSender bean exists and is correctly wired into other classes) The following things confuse me:
- Is context:component-scan supposed to be picking up @Aspect? If it is then surely it would be a spring managed bean, thus autowired should work?
- If context:component-scan isn't for creating aspects, how is my aspect being created? I thought aop:aspectj-autoproxy just creates a beanPostProcessor to proxy my @Aspect class? How would it do this if it isn't a spring managed bean?
Obviously you can tell I don't have an understanding of how things should be working from the ground up.
Use compile time weaving, see for plugin example at: https://github.com/avner-levy/minimal_spring_hibernate_maven_setup/blob/master/pom.xml
The following combination of annotation and Spring config works for me thanks to notes above by Tobias/Willie/Eric:
Class:
XML:
Configuring @Autowired with java config only (so no XML based configuration) requires a bit of extra work than just adding @Configuration to the class, as it also needs the aspectOf method.
What worked for me was creating a new class:
And then use that in you aspect in conjunction with using @DependsOn @Configured and @Autowired:
The @DependsOn is needed because spring can't determine the dependency because the bean is used staticly.
This blog post explains it really well. Due to the fact that aspect singleton is created outside spring container you'd need to use factory-method=”aspectOf” that is only available after it is woven in by AspectJ ( not Spring AOP ) :
So that :
From my experience with spring 3.1, if I don't use @Autowired but traditional setter for dependency injection, it gets injected and works as expected without aspectJ weaver. Although I'm encountering problems with the aspect being singleton... It results in 'perthis' instantiation model. .
Another option is to add
@Configurable
to your aspect class instead of messing around with XML.I dont have 50 rep to comment on a question so here is another answer relating to @ Jitendra Vispute answer. The official Spring doc mentions:
This would mean that adding a @Component annotation and adding the @ComponentScan on your Configuration would make @Jitendra Vispute's example work. For the spring boot aop sample it worked, though I did not mess around with context refreshing.Spring boot aop sample:
Application:
The application should also run as plain Spring Framework application with the following annotations instead of @SpringBootApplication:
and an AnnotationConfigApplicationContext instead of SpringApplication.
Service:
Monitor Aspect:
Add @Component to aspect class and your dependencies should get injected automatically. and add context:component-scan for package where your aspect is in spring context file.