假设我有一个春季启动应用程序
@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);
}
}
我的aspectJ类
@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();
}
}
我希望在Spring启动之前准备好此Aspect。这可能是我想做的吗?由于某些我不知道的原因,这方面没有被截获。
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>
我没有使用弹簧靴启动器。以上是我用于aop的所有配置和代码。
答案 0 :(得分:3)
由于Spring框架基于代理的特性,Spring AOP基于运行时编织。这意味着目标类在Spring运行时期间变为代理。
在大多数情况下,Spring框架不会对其框架类进行代理。您感兴趣的课程CommonAnnotationBeanPostProcessor
未被代理。因此,Spring AOP无法拦截对ignoreResourceType
的{{1}}方法的任何调用。
但是,这并不意味着你运气不好。您仍然可以利用AspectJ的二进制编织。
在二进制编织中,目标和方面源代码(* .java)分别编译为二进制类(.class)。然后将二进制类与AspectJ编译器(ajc)编织在一起。
在您的情况下,方面源代码(CommonAnnotationBeanPostProcessor
)将使用AspectJ编译器编译为二进制类(AOP.java
)。 AOP.class
和现有的Spring类AOP.class
将一起编织成一个新的编织CommonAnnotationBeanPostProcessor.class
。
以下是类CommonAnnotationBeanPostProcessor.class
的{{1}}方法的代码段,
ignoreResourceType
现在,请注意方法由AspectJ编织后的更改。
CommonAnnotationBeanPostProcessor
public void ignoreResourceType(String resourceType) {
Assert.notNull(resourceType, "Ignored resource type must not be null");
this.ignoredResourceTypes.add(resourceType);
}
下包含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
的插件部分的摘录。您可以找到一个完整的工作示例here。
weaveDependencies
答案 1 :(得分:0)
在我看来,你想拦截Spring类中的方法执行。为此,您有两种选择:
-javaagent:/path/to/aspectjweaver-<version>.jar
作为JVM参数)在构建时编写Spring库类以创建库的特殊编织版本(see relevant aspectj-maven-plugin documentation),并使用生成的weaved类而不是原始的spring jar文件。您得到的配置看起来与此类似:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<configuration>
<weaveDependencies>
<weaveDependency>
<groupId>org.agroup</groupId>
<artifactId>to-weave</artifactId>
</weaveDependency>
<weaveDependency>
<groupId>org.anothergroup</groupId>
<artifactId>gen</artifactId>
</weaveDependency>
</weaveDependencies>
</configuration>
</plugin>