带有原型bean的Spring AOP

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

我正在使用Spring AOP在我们的应用程序中触发指标。我创建了一个注释@CaptureMetrics,它具有与之相关的@around建议。可以从带有@CaptureMetrics标记的所有方法中很好地调用建议,除了情况当在原型bean上调用方法时。

注释具有@Target({ElementType.TYPE, ElementType.METHOD})

PointCut表达式:

@Around(value = "execution(* *.*(..)) && @annotation(captureMetrics)",
      argNames = "joinPoint,captureMetrics")

原型bean创建

@Bean
  @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
  public DummyService getDummyServicePrototypeBean(int a, String b) {
    return new DummyService(a, b);
  }

DummyService具有一个称为dummyMethod(String dummyString)的方法

    @CaptureMetrics(type = MetricType.SOME_TYPE, name = "XYZ")
          public Response dummyMethod(id) throws Exception {
           // Do some work here
        }

[从其他服务调用dummyService.dummyMethod("123")时,未调用@Around建议。

Config class

@Configuration
public class DummyServiceConfig {

  @Bean
  public DummyServiceRegistry dummyServiceRegistry(
      @Value("${timeout}") Integer timeout,
      @Value("${dummy.secrets.path}") Resource dummySecretsPath) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    Map<String, String> transactionSourceToTokens = mapper.readValue(
        dummySecretsPath.getFile(), new TypeReference<Map<String, String>>() {
        });
    DummyServiceRegistry registry = new DummyServiceRegistry();
    transactionSourceToTokens.forEach((transactionSource, token) ->
        registry.register(transactionSource,
            getDummyServicePrototypeBean(timeout, token)));

    return registry;
  }

  @Bean
  @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
  public DummyService getDummyServicePrototypeBean(int a, String b) {
    return new DummyService(a, b);
  }

}

Singleton Registry类

public class DummyServiceRegistry {
  private final Map<String, DummyService> transactionSourceToService = new HashMap<>();

  public void register(String transactionSource, DummyService dummyService) {
    this.transactionSourceToService.put(transactionSource, dummyService);
  }

  public Optional<DummyService> lookup(String transactionSource) {
    return Optional.ofNullable(transactionSourceToService.get(transactionSource));
  }
}

对此有任何建议吗?

注意:

  • 原型Dummy服务用于呼叫第三方客户端。它是原型Bean,因为它的状态因要调用第三方的代表而异。

  • 初始化期间的单例注册表bean会构建{source_of_request,dummyService_prototype}的映射。要获取dummyService原型,它调用getDummyServicePrototypeBean()

spring-boot prototype javabeans aop spring-aop
1个回答
0
投票

配置,注册表和原型虚拟bean都是正确的。

我正在使用现有的集成测试来测试流程,并且在那里没有提供原型Bean,而是使用new关键字实例化了DummyService的新对象。它不是Spring管理的Bean。

Spring AOP仅适用于Spring托管的bean。

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