article/java/使用LoadTimeWeaving技术实现AOP功能.md
2022-08-28 14:57:12 +08:00

245 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 使用LTW(LoadTimeWeaving)技术实现AOP功能
### aop增强分类
###### 编译时:
使用特殊的编译器在编译期将切面织入目标类,这种比较少见,因为需要特殊的编译器的支持。例如AspectJ编译 器,很少有到,目前我还没有用到。
###### 加载时:
通过字节码编辑技术在类加载期将切面织入目标类中,它的核心思想是在目标类的class文件被JVM加 载前,通过自定义类加载器或者类文件转换器将横切逻辑织入到目标类的class文件中然后将修改后class文件交给JVM加载 这种织入方式可以简称为LTW(LoadTimeWeaving)AspectJ的LoadTimeWeaving (LTW)
###### 运行时:
运行期通过为目标类生成动态代理的方式实现AOP就属于运行期织入这也是Spring AOP中的默认实现,并且提供了两种创建动态代理的方式JDK自带的针对接口的动态代理和使用CGLib动态创建子类的方式创建动态代理。
### 优劣势
编译时:需要特殊的编译器
加载时:需要特殊的类加载器
运行时:功能有限
### 使用LTW 切面第三方JAR 包普通maven项目
#### 配置文件
##### pom 文件
```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.x47.blog</groupId>
<artifactId>LoadTimeWeaving-demo</artifactId>
<version>1.0</version>
</parent>
<artifactId>java-aspectj-agent</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>cn.x47.ltw.Main</mainClass><!--这里改成自己的主类位置-->
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
```
##### aop.xml
放在`META-INF/aop.xml`
```xml
<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "https://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver>
<!-- 注意 目标类 和使用目标类方法的类都要配置 -->
<include within="cn.x47.ltw..*"/>
<include within="com.alibaba.fastjson.*"/>
</weaver>
<aspects>
<!-- 切面 -->
<aspect name="cn.x47.ltw.ProfilingAspect"/>
</aspects>
</aspectj>
```
### 目录结构
![image-20220828130642183](http://pic.61dz.com/pic/image-20220828130642183.png)
### 执行方法
##### 开发环境
可以通过添加jvm参数的方式来启动
![image-20220828123756596](http://pic.61dz.com/pic/image-20220828123756596.png)
### springboot 使用 LTW切面第三方JAR包
#### 配置文件
##### pom配置
```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.x47.blog</groupId>
<artifactId>LoadTimeWeaving-demo</artifactId>
<version>1.0</version>
</parent>
<artifactId>springboot-aspectj-agent</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.9</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
```
##### oop配置
```xml
<?xml version="1.0" encoding="UTF-8" ?>
<aspectj>
<weaver options="-XnoInline -Xset:weaveJavaxPackages=true -Xlint:ignore -verbose -XmessageHandlerClass:org.springframework.aop.aspectj.AspectJWeaverMessageHandler">
<!--在编织时导入切面类和需要被切入的目标类-->
<include within="cn.x47.ltw..*"/>
<include within="com.alibaba.fastjson..*"/>
</weaver>
<aspects>
<!--指定切面类-->
<aspect name="cn.x47.ltw.springboot.aop.TestAspect"/>
</aspects>
</aspectj>
```
#### 目录结构
![image-20220828135835641](http://pic.61dz.com/pic/image-20220828135835641.png)
### 源码地址
https://git.dr1997.com/blog/LoadTimeWeaving-demo