aop之agent增强
除了之前讲的添加Aspect插件方式可以实现Aop,还有另一种实现,修改Vm options参数可以在类加载时候进行增强,本质也是修改class文件进行增强。
1.依赖准备
<?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><groupId>com.example</groupId><artifactId>springDemo</artifactId><version>0.0.1-SNAPSHOT</version><name>springDemo</name><description>springDemo</description><properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><spring-boot.version>2.6.13</spring-boot.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-indexer</artifactId><version>5.3.23</version><optional>true</optional> <!-- 推荐设置为 optional,防止传递到其他模块 --></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!-- AspectJ Weaver --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.7</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.9.7</version></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>${spring-boot.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target><encoding>UTF-8</encoding></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>${spring-boot.version}</version><configuration><mainClass>com.example.springdemo.SpringDemoApplication</mainClass><skip>true</skip></configuration><executions><execution><id>repackage</id><goals><goal>repackage</goal></goals></execution></executions></plugin></plugins></build>
</project>
不需要引入插件依赖,引入Aspectj的相关依赖。
2.在META-INF下准备aop.xml文件
<!DOCTYPE aspectj PUBLIC"-//AspectJ//DTD//EN""http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj><aspects><!-- 确保类路径正确 --><aspect name="com.example.springdemo.demos.a28.aop.MyAspect"/></aspects><weaver options="-verbose -showWeaveInfo -debug"><!-- 明确包含切面所在的包 --><include within="com.example.springdemo.demos.a28.aop..*"/><include within="com.example.springdemo.demos.a28.service..*"/><!-- 排除可能冲突的包 --><exclude within="*Test*"/><exclude within="com.example.springdemo.demos.a28.config..*"/></weaver>
</aspectj>
3.MyAspect
package com.example.springdemo.demos.a28.aop;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;/*** @author zhou* @version 1.0* @description TODO* @date 2025/10/18 20:04*/
@Aspect
public class MyAspect {private static final Logger log = LoggerFactory.getLogger(MyAspect.class);@Before("execution(* com.example.springdemo.demos.a28.service.MyService.*(..))")public void before(){log.info("before()");}}
对MySerivice中的所有方法都进行了增强。
4.Myservice
package com.example.springdemo.demos.a28.service;import com.example.springdemo.demos.a27.a27Application;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;/*** @author zhou* @version 1.0* @description TODO* @date 2025/10/18 20:08*/
@Service
public class MyService {private static final Logger log = LoggerFactory.getLogger(MyService.class);public void test(){log.info("test");bar();}public void bar(){log.info("bar");}
}
5.测试主类
package com.example.springdemo.demos.a28;import com.example.springdemo.demos.a27.a27Application;
import com.example.springdemo.demos.a28.service.MyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;/*** @author zhou* @version 1.0* @description TODO* @date 2025/10/18 20:08*/
@SpringBootApplication
public class a28Application {private static final Logger log = LoggerFactory.getLogger(a28Application.class);public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(a28Application.class, args);MyService service = context.getBean(MyService.class);log.info("service class:{}",service.getClass());service.test();context.close();}
}
配置vm参数:-javaagent:D:/work/repository/org/aspectj/aspectjweaver/1.9.7/aspectjweaver-1.9.7.jar(选择本地下载的aspectjweaver文件的路径)
6.运行结果
test和bar方法都得到了增强。使用Arthas工具可以查看编译后的class文件,在两个反法前都进行了增强。我们的通过test方法调用的bar方法,如果使用动态代理的话,bar方法的增强可能会实现,因为的通过本地调用。