spring5 aop之ajc增强
除了 JDK 动态代理和 CGLIB,Spring AOP 还支持 AspectJ AOP 容器(ajc)增强。
AspectJ AOP 是 Spring AOP 的一个扩展方案,它提供了比 Spring AOP 更强大、更灵活、更高效的 AOP 功能。AspectJ AOP 不仅支持方法级别的增强,还支持属性、构造函数和静态切面等增强。
AspectJ AOP 容器(ajc)是 AspectJ 中的编译器,它将 AspectJ 代码编译成 Java 字节代码。在 Spring AOP 中使用时,Spring 将 AspectJ 代码编译成的 Java 字节代码与目标类进行织入,从而实现 AOP 功能。
使用 AspectJ AOP 的步骤如下:
- 在 pom.xml 中添加 AspectJ 依赖:
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <version>${aspectj.version}</version> </dependency>
讯享网
- 添加 ajc 编译器插件:
讯享网 <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.14.0</version> <configuration> <complianceLevel>1.8</complianceLevel> <source>8</source> <target>8</target> <showWeaveInfo>true</showWeaveInfo> <verbose>true</verbose> <Xlint>ignore</Xlint> <encoding>UTF-8</encoding> </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> </build>
- 创建 AspectJ 切面:
package com.itheima.aop; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Aspect // ⬅️注意此切面并未被 Spring 管理 public class MyAspect {
private static final Logger log = LoggerFactory.getLogger(MyAspect.class); @Before("execution(* com.itheima.service.MyService.foo())") public void before() {
log.debug("before()"); } }
- 在目标类中使用 AspectJ AOP 切面
通过使用 AspectJ AOP,我们可以获得比 Spring AOP 更高效、灵活和功能更强大的 AOP 功能。但是,AspectJ AOP 需要更加熟练的 AspectJ 编程技巧和更复杂的配置,对于一些简单的应用场景,可能不是必要的选择。
完整代码
A10

MyService

MyAspect

运行一下查看结果,这里需要用maven编译一下(我们发现不是用代理来增强的):


这时你可以把MyService.class文件找到看一下发现它是直接改写了class文件进行增强的

大家想,既然都改写了class文件,那么就与spring容器没关系了,其实也并不是spring管理的,是AspectJ的编译器来读到切面进行增强,我们把spring的context注释,直接new出来试一下

看结果(依然增强了):

不过在spring中使用的不是很广泛,而且需要注意编译的时候需要用maven的编译,idea的编译调的是javac那个编译器,就走不到aspectJ插件,结果就会达不到我们的预期。
比代理好的地方即为可以增强static修饰的方法,使用代理的话是不行的,继承父类或、继承接口的Proxy都不能重写静态方法。
收获
- 编译器也能修改 class 实现增强
- 编译器增强能突破代理仅能通过方法重写增强的限制:可以对构造方法、静态方法等实现增强
注意
- 版本选择了 java 8, 因为用的 aspectj-maven-plugin 1.14.0 最高只支持到 java 16
- 一定要用 maven 的 compile 来编译, idea 不会调用 ajc 编译器

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/39494.html