SpringAOP-AspectJ
AspectJ 与 Advisor 区别
Spring AOP和AspectJ虽然都支持@Aspect注解,但底层实现完全不同:
| 特性 | Spring AOP | AspectJ |
|---|---|---|
| 实现方式 | 运行时动态代理 | 编译期/加载时字节码增强 |
| 拦截范围 | 仅Spring Bean的public方法 | 任意Java对象(包括构造器、字段等) |
| 性能影响 | 有代理调用开销 | 无运行时损耗 |
| 依赖 | Spring容器 | 需AspectJ编译器或织入器 |
Spring 集成 AspectJ 的两种方式
加载时织入(LTW)
配置步骤:添加 maven 依赖、启用 LTW(配置文件或JVM参数二选一)。不需要配置 maven 插件
- 添加依赖:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.7</version>
</dependency>
- 启用 LTW:
如果是 Spring 项目,没有配置文件,使用 @EnableLoadTimeWeaving 注解来开启
如果是 SpringBoot 项目可以配置文件开启,配置如下:
# application.properties
spring.aop.weaving=enable
- 或使用JVM参数:
-javaagent:/path/to/aspectjweaver.jar
编译时织入(CTW)
只需要配置 maven 插件就行了(不需要 JVM 参数、配置文件、maven 依赖)
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.14.0</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
AspectJ 示例
如果是想要前置、后置、环绕等通知,直接使用 SpringAOP(Advisor)
Advisor 和 AspectJ 可以共存,两者并不冲突
示例1:拦截对象构造
@Aspect // 没有 @Conponent 注解
public class ConstructionMonitorAspect {
// 拦截所有ArrayList的构造
@After("call(java.util.ArrayList.new(..))")
public void afterArrayListCreation(JoinPoint jp) {
System.out.println("ArrayList创建于: " + jp.getSourceLocation());
}
}
示例2:字段访问监控
@Aspect // 没有 @Conponent 注解
public class FieldAccessAspect {
// 拦截User对象的name字段读取
@Before("get(* com.example.model.User.name)")
public void beforeFieldRead(JoinPoint jp) {
System.out.println("正在读取name字段");
}
}
示例3:静态方法拦截
@Aspect // 没有 @Conponent 注解
public class StaticMethodAspect {
// 拦截Math类的random方法调用
@Around("call(public static double java.lang.Math.random())")
public Object aroundRandomCall(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("Math.random()被调用");
return pjp.proceed();
}
}

浙公网安备 33010602011771号