You need to use a real AspectJ aspect with Spring, where you would like to inject some dependencies into this aspect as a Spring container starts up.
Here is an AspectJ aspect:
@Aspect public class VeryImportantAspect { ... public void setSomeDependency( SomeDependency dependency ) { this.dependency = dependency; } ... } |
Now let’s define it as a bean and inject “someDependency”:
<bean id="veryImportantAspect" class="org.dotkam.VeryImportantAspect" factory-method="aspectOf"> <property name="someDependency" ref="someDependency"/> </bean> |
Notice factory-method=”aspectOf” that tells Spring to use a real AspectJ ( not Spring AOP ) aspect to create this bean. In reality, if the “VeryImportantAspect” was already woven in, it will have an “aspectOf” method.
Hence if you get this error at some point:
No matching factory method found: factory method 'aspectOf()' |
That would mean that the aspect was not woven by AspectJ weaver.
We also need to tell Spring to use load time weaving:
<context:load-time-weaver/> |
If you run with the above configuration without doing anything, you would get a following error:
ClassLoader does NOT provide an 'addTransformer(ClassFileTransformer)' method |
That tells you ( well not explicitly :) ) to include a “spring-instrument.jar” javaagent.
So at this point two things need to be added: AspectJ weaver and Spring Instrument agent. Build / Continues integration server does not use any IDE, so it is not as simple as downloading AspectJ plugin for IDEA / Eclipse and including VM arguments in Run Configurations… It is simpler: just add the two in your POM file.
Adding an AspectJ plugin:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.3</version> <executions> <execution> <configuration> <source>1.6</source> <target>1.6</target> </configuration> <goals> <goal>compile</goal> <!-- use this goal to weave all your main classes --> <goal>test-compile</goal> <!-- use this goal to weave all your test classes --> </goals> </execution> </executions> </plugin> |
Adding a Spring Instrument agent to participate in a test execution:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>2.4</version> <configuration> <forkMode>once</forkMode> <argLine> -javaagent:"${settings.localRepository}/org/springframework/spring-instrument/${spring.framework.version}/spring-instrument-${spring.framework.version}.jar" </argLine> <useSystemClassloader>true</useSystemClassloader> </configuration> </plugin> |
And all that work, just too see a couple of lines from Maven:
[INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ |