Suppose i have a spring boot application
@SpringBootApplication
public abstract class AbstractMicroServer {
public static void main(final String[] args) {
// here some asppect should start
final SpringApplication app = new SpringApplication(AbstractMicroServer.class);
app.run(args);
}
}
My aspectJ class
@Aspect
public class AOP{
@Pointcut("execution(* org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.ignoreResourceType(..)")
public void intercept() {
}
@Around("intercept()")
public Object intercept(final ProceedingJoinPoint joinPoint) throws Throwable {
return joinPoint.getArgs();
}
}
I want this Aspect to be ready before spring boot starts. Is this possible what i want to do ? The aspect is not getting intercepted for some reason which i dont know.
POM
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.12</version><!--$NO-MVN-MAN-VER$ -->
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.12</version><!--$NO-MVN-MAN-VER$-->
</dependency>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<source>1.8</source>
<target>1.8</target>
<showWeaveInfo>true</showWeaveInfo>
<verbose>true</verbose>
<Xlint>ignore</Xlint>
<encoding>UTF-8</encoding>
<includes>
<include>**/*.java</include>
<include>**/*.aj</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<!-- use this goal to weave all your main classes -->
<goal>compile</goal>
<!-- use this goal to weave all your test classes -->
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
I am not using spring boot starter aop. Above are all the configuration and code i have for aop.
The Spring AOP is based on runtime weaving due to the proxy-based nature of the Spring framework. This means the target class is turned into a proxy during Spring runtime.
In most cases, the Spring framework doesn't make a proxy of its frameworks classes. The class you are interested, CommonAnnotationBeanPostProcessor
, is not proxied. Therefore, Spring AOP cannot intercept any calls to ignoreResourceType
method of CommonAnnotationBeanPostProcessor
.
However, it doesn't mean you are out of luck. You can still take advantage of AspectJ's binary weaving.
In binary weaving, the target and aspect source code (*.java) are compiled separately into binary classes (.class). The binary classes are then woven together with AspectJ compiler (ajc).
In your case, the aspect source code (AOP.java
) will be compiled with AspectJ compiler into a binary class (AOP.class
). The AOP.class
and the existing Spring class, CommonAnnotationBeanPostProcessor.class
will be weaved to together into a new weaved CommonAnnotationBeanPostProcessor.class
.
Here is the code snippet of ignoreResourceType
method of class CommonAnnotationBeanPostProcessor
,
public void ignoreResourceType(String resourceType) {
Assert.notNull(resourceType, "Ignored resource type must not be null");
this.ignoredResourceTypes.add(resourceType);
}
Now, notice the changes after the method is woven by AspectJ.
public void ignoreResourceType(String resourceType) {
JoinPoint var3 = Factory.makeJP(ajc$tjp_0, this, this, resourceType);
SpringFrameworkClassAspect var10000 = SpringFrameworkClassAspect.aspectOf();
Object[] var4 = new Object[]{this, resourceType, var3};
var10000.adviceAround((new CommonAnnotationBeanPostProcessor$AjcClosure1(var4)).linkClosureAndJoinPoint(69648));
}
spring-context
dependency under weaveDependencies
.Below is an excerpt from the plugin section of your project's pom.xml
. You can find a complete working example here.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<showWeaveInfo/>
<source>1.8</source>
<target>1.8</target>
<complianceLevel>${java.version}</complianceLevel>
<Xlint>ignore</Xlint>
<forceAjcCompile>true</forceAjcCompile>
<sources/>
<weaveDirectories>
<weaveDirectory>${project.build.directory}/classes</weaveDirectory>
</weaveDirectories>
<weaveDependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
</weaveDependencies>
<aspectLibraries>
<aspectLibrary>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>