如何判断Spring Boot中Load Time Weaving是否正常生效?
关于Spring Boot 3.0.12中Load Time Weaving(LTW)生效验证的问题
环境与配置
- Spring Boot版本:3.0.12
- 已完成的LTW相关配置:
- 在
META-INF目录下创建aop.xml:<aspectj> <aspects> <aspect name="com.example.helloworld.aspects.DaoExceptionHandler"/> <weaver options="-verbose -showWeaveInfo"> <include within="com.example.helloworld.*"/> </weaver> </aspects> </aspectj> - 启动应用时添加Java代理参数:
-javaagent:/Users/dm/.m2/repository/org/aspectj/aspectjweaver/1.9.20/aspectjweaver-1.9.20.jar - pom.xml中引入AspectJ依赖:
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.9.20</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.20</version> </dependency>
- 在
切面与目标类实现
切面代码
@Aspect @Slf4j public class DaoExceptionHandler { @AfterThrowing( pointcut = "execution(* *(..)) &&" + " @annotation(com.example.helloworld.utils.HandleDaoException)", throwing = "ex") public void handle(RuntimeException ex) { log.error("Exception received on dao", ex); throw JooqUtil.mapException(ex); } }
目标类(使用自定义注解)
@Component public class DaoImpl { @HandleDaoException public void getError() { throw new IllegalArgumentException("Test"); } }
启动与运行现象
- 启动日志显示AspectJ织入器已加载并读取配置:
2024-04-23T16:21:08.770+05:30 INFO 33973 --- [ main] c.e.helloworld.HelloWorldApplication : Started HelloWorldApplication in 0.797 seconds (process running for 1.13) [MethodUtil@4b627298] info AspectJ Weaver Version 1.9.20 built on Tuesday Aug 15, 2023 at 23:35:34 PDT [MethodUtil@4b627298] info register classloader sun.reflect.misc.MethodUtil@4b627298 [MethodUtil@4b627298] info using configuration /Users/debrajmanna/code/java/github/spring-boot-hello-world/target/classes/META-INF/aop.xml [MethodUtil@4b627298] info register aspect com.example.helloworld.aspects.DaoExceptionHandler - 调用接口
curl --request GET 'http://localhost:8080/hello'触发异常后,栈追踪显示仍在使用CGLIB代理:java.lang.IllegalArgumentException: Test at com.example.helloworld.dao.DaoImpl.getError(DaoImpl.java:10) ~[classes/:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na] at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na] at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na] at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na] at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) ~[spring-aop-6.0.13.jar:6.0.13] at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.0.13.jar:6.0.13] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.0.13.jar:6.0.13] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751) ~[spring-aop-6.0.13.jar:6.0.13] at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:64) ~[spring-aop-6.0.13.jar:6.0.13] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:173) ~[spring-aop-6.0.13.jar:6.0.13] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751) ~[spring-aop-6.0.13.jar:6.0.13] at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97) ~[spring-aop-6.0.13.jar:6.0.13] at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.0.13.jar:6.0.13] at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:751) ~[spring-aop-6.0.13.jar:6.0.13] at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:703) ~[spring-aop-6.0.13.jar:6.0.13] at com.example.helloworld.dao.DaoImpl$$SpringCGLIB$$0.getError(<generated>) ~[classes/:na] ... - 即使移除
-javaagent参数并添加@EnableAspectJAutoProxy,栈追踪依然显示使用CGLIB代理。
疑问
我原本理解:未启用LTW时Spring默认使用CGLIB代理,但现在已经配置了LTW,栈追踪却还是显示CGLIB在工作。请问我的理解是否有误?如何正确判断Spring中Load Time Weaving是否正常生效?
内容的提问来源于stack exchange,提问作者tuk
相关产品推荐
相关产品推荐

