如何使spring注入bean与aspectj的加载时间编织?

问题描述 投票:0回答:1

可复制的项目位于此处。 (分支 -

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 吗?

java spring aspectj spring-aop
1个回答
0
投票
正如我所说,

@Configurable

Spring 文档可能会有所帮助。还有一个 Baeldung 教程

你需要

  • spring-aspects
    依赖,
  • @EnableSpringConfigured
     在你的配置类中,
  • @Autowired
    在你的方面。
Lombok 生成的

@AllArgsConstructor

 不使用 
@Autowired
@Inject
,这就是构造函数注入不起作用的原因。此外,
@Component
注释对于本机方面也是错误的。您只需要 Spring AOP 方面的内容。

请参阅我的

拉取请求了解详细信息。

© www.soinside.com 2019 - 2024. All rights reserved.