详解 Spring AOP LoadTimeWeaving (LTW) https://blog.csdn.net/c39660570/article/details/106791365/
官方文档 https://docs.spring.io/spring-framework/docs/5.3.x/reference/html/core.html#aop-aj-ltw
SpringBoot中使用LoadTimeWeaving技术实现AOP功能 https://juejin.cn/post/6844903873748926472
LTW 可以解决的问题
非 spring 管理的类依赖注入和切面不生效的问题。
调用类内方法切面不生效的问题。 (private方法等)
- 本质是agent,开发方式与sdk一致,可以方便地debug
切面织入时机分类
编译期织入
使用特殊的编译器在编译期将切面织入目标类,这种比较少见,因为需要特殊的编译器的支持。
加载时织入
通过字节码编辑技术在类加载期将切面织入目标类中。
它的核心思想是:在目标类的class文件被JVM加载前,通过自定义类加载器或者类文件转换器将横切逻辑织入到目标类的class文件中,然后将修改后class文件交给JVM加载。
这种织入方式可以简称为LTW(LoadTimeWeaving)。
运行期织入
这是最常见的,比如在运行期通过为目标类生成动态代理的方式实现AOP就属于运行期织入,这也是Spring AOP中的默认实现,
并且提供了两种创建动态代理的方式: JDK自带的针对接口的动态代理 和 使用CGLib动态创建子类的方式创建动态代理。
LTW使用
LTW使用与aop动态代理方式可以共存,但是使用方式是不同的。(使用方式不能混用,容易出现一些非预期的现象)
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-instrument</artifactId>
</dependency>
开启功能
@Configuration
/**开启LTW, 有aop.xml文件配置才会生效**/
@EnableLoadTimeWeaving
/**LTW切面支持spring bean注入**/
@EnableSpringConfigured
public class AopConfig {
}
增加一个切面
aop.xml
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<!-- Add this argument to options to make AspectJ logs use the Spring logging framework. -->
<!-- -XmessageHandlerClass:org.springframework.aop.aspectj.AspectJWeaverMessageHandler -->
<weaver options="-verbose -showWeaveInfo">
<!--
Only weave classes in our application-specific packages.
This should encompass any class that wants to utilize the aspects,
and does not need to encompass the aspects themselves.
-->
<!-- <include within="org.apache.dubbo.rpc.protocol.dubbo..*" />
-->
</weaver>
<aspects>
<!-- declare aspects to the weaver -->
<aspect name="com.myhexin.devops.qa.mock.stub.infrastructure.aop.DubboDecodeAspect"/>
</aspects>
</aspectj>
切面类
不能声明为spring的bean
@Aspect
/**切面支持spring bean注入**/
@Configurable
public class DubboDecodeAspect {
@Autowired
public Aaxx aaxx;
@Around("execution(* org.apache.dubbo.rpc.protocol.dubbo.DecodeableRpcInvocation.decode(..))")
public Object decode(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("dubbo test");
System.out.println(aaxx);
System.out.println(HexinInnerSpringContextContainer.getBeanByType(Aaxx.class));
return pjp.proceed();
}
}
启动进行测试
java -javaagent:{path}/spring-instrument.jar -jar main.jar
spring-instrument.jar, 可以使用maven-dependency-plugin在打包阶段拷贝到项目中
版权声明:《 spring aop LoadTimeWeaving(LTW), 可以debug的agent 》为Saber原创文章,转载请注明出处!
最后编辑:2024-5-11 03:05:58