可复制的项目位于此处。 (分支 -
aspect_autowire
)。调用以下命令来重现问题
curl --request GET 'http://localhost:8080/hello'`
我的方面是代码如下
@Aspect
@Slf4j
@AllArgsConstructor
@Component
public class DaoExceptionHandler {
private final Map<Long, String> errorLogMap;
@AfterThrowing(
pointcut =
"execution(* *(..)) &&"
+ " @annotation(com.example.helloworld.utils.HandleDaoException)",
throwing = "ex")
public void handle(RuntimeException ex) {
errorLogMap.put(System.currentTimeMillis(), ex.getMessage());
log.error("Exception received on dao", ex);
log.error("Error Log Map Content: {}", errorLogMap);
throw JooqUtil.mapException(ex);
}
}
errorLogMap
bean 定义如下
@Configuration
@Slf4j
@EnableLoadTimeWeaving
public class AspectConfig {
@Bean
public Map<Long, String> errorLogMap() {
log.info("Initialising Bean");
return new HashMap();
}
}
aop.xml
放置在 src/main/resources/META-INF
中,如下
<aspectj>
<aspects>
<aspect name="com.example.helloworld.aspects.DaoExceptionHandler"/>
<weaver options="-verbose -showWeaveInfo">
<include within="com.example.helloworld..*"/>
</weaver>
</aspects>
</aspectj>
-javaagents
在运行应用程序时指定如下
-Djava.rmi.server.hostname=localhost -javaagent:/Users/debrajmanna/.m2/repository/org/aspectj/aspectjweaver/1.9.20/aspectjweaver-1.9.20.jar -javaagent:/Users/debrajmanna/.m2/repository/org/springframework/spring-instrument/6.0.13/spring-instrument-6.0.13.jar
在启动过程中,我看到如下日志
OpenJDK 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.
[AppClassLoader@251a69d7] info AspectJ Weaver Version 1.9.20 built on Tuesday Aug 15, 2023 at 23:35:34 PDT
[AppClassLoader@251a69d7] info register classloader jdk.internal.loader.ClassLoaders$AppClassLoader@251a69d7
[AppClassLoader@251a69d7] info using configuration /Users/debrajmanna/code/java/github/spring-boot-hello-world/target/classes/META-INF/aop.xml
[AppClassLoader@251a69d7] info register aspect com.example.helloworld.aspects.DaoExceptionHandler
...
2024-04-28T15:15:20.616+05:30 INFO 87296 --- [ main] c.e.helloworld.HelloWorldApplication : No active profile set, falling back to 1 default profile: "default"
[AppClassLoader@251a69d7] weaveinfo Join point 'method-execution(void com.example.helloworld.dao.DaoImpl.getError())' in Type 'com.example.helloworld.dao.DaoImpl' (DaoImpl.java:10) advised by afterThrowing advice from 'com.example.helloworld.aspects.DaoExceptionHandler' (DaoExceptionHandler.java)
...
[MethodUtil@3209a8de] info AspectJ Weaver Version 1.9.20 built on Tuesday Aug 15, 2023 at 23:35:34 PDT
[MethodUtil@3209a8de] info register classloader sun.reflect.misc.MethodUtil@3209a8de
[MethodUtil@3209a8de] info using configuration /Users/debrajmanna/code/java/github/spring-boot-hello-world/target/classes/META-INF/aop.xml
[MethodUtil@3209a8de] info register aspect com.example.helloworld.aspects.DaoExceptionHandler
但是方面代码并未全部被调用。我只能看到
2024-04-28T15:17:36.104+05:30 WARN 87296 --- [nio-8080-exec-2] c.e.h.controller.HelloWorldController : Ignoring exception
如果我只是注释DaoExceptionHandler中errorLogMap的用法
public class DaoExceptionHandler {
// private final Map<Long, String> errorLogMap;
@AfterThrowing(
pointcut =
"execution(* *(..)) &&"
+ " @annotation(com.example.helloworld.utils.HandleDaoException)",
throwing = "ex")
public void handle(RuntimeException ex) {
// errorLogMap.put(System.currentTimeMillis(), ex.getMessage());
log.error("Exception received on dao", ex);
// log.error("Error Log Map Content: {}", errorLogMap);
throw JooqUtil.mapException(ex);
}
}
我可以看到方面代码被调用。
2024-04-28T15:19:32.100+05:30 ERROR 88735 --- [nio-8080-exec-1] c.e.h.aspects.DaoExceptionHandler : Exception received on dao
java.lang.IllegalArgumentException: Test
at com.example.helloworld.dao.DaoImpl.getError(DaoImpl.java:10) ~[classes/:na]
at com.example.helloworld.controller.HelloWorldController.sendGreetings(HelloWorldController.java:17) ~[classes/:na]
...
如果我指定
@EnableAspectJAutoProxy
代替 EnableLoadTimeWeaving
中的 AspectConfig
并删除两个 javaagent
,则 errorLogMap()
会正确注入到 DaoExceptionHandler
中,并且该方面也会被调用。
使用
@EnabledLoadTimeWeaving
我尝试仅添加 aspectjweaver-1.9.20.jar
作为 -javaagent。但这并非没有帮助。所以添加 spring-instrument.jar
也作为 -javaagent
。但这也无济于事。有人可以建议是否可以使用带有加载时编织方面的 spring bean 吗?
的Spring 文档可能会有所帮助。还有一个 Baeldung 教程。 你需要
spring-aspects
依赖,
@EnableSpringConfigured
在你的配置类中,
@Autowired
在你的方面。
@AllArgsConstructor
不使用
@Autowired
或
@Inject
,这就是构造函数注入不起作用的原因。此外,
@Component
注释对于本机方面也是错误的。您只需要 Spring AOP 方面的内容。请参阅我的
拉取请求了解详细信息。