我正在使用Spring AOP在我们的应用程序中触发指标。我创建了一个注释@CaptureMetrics
其中包含与之相关的@around
建议。从所有标记为@CaptureMetrics
的方法中都可以很好地调用该建议,除了在原型 Bean 上调用方法的情况。
批注具有@Target({ElementType.TYPE, ElementType.METHOD})
切入点表达式:
@Around(value = "execution(* *.*(..)) && @annotation(captureMetrics)",
argNames = "joinPoint,captureMetrics")
原型豆创建
@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
建议。
配置类
@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);
}
}
单例注册表类
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));
}
}
请问有什么建议吗?
注意:
原型虚拟服务用于调用第三方客户端。它是一个原型 bean,因为它的状态根据它将代表谁调用第三方而有所不同。
初始化期间的单例注册表 Bean 会构建 {source_of_request, dummyService_prototype} 的映射。为了获得虚拟服务原型,它调用getDummyServicePrototypeBean((
配置、注册表和原型假豆是正确的。
我正在使用现有的集成测试来测试流程,在那里没有提供原型 Bean,而是使用new
关键字实例化了 DummyService 的新对象。这不是春天管理的豆子。
SpringAOP 仅适用于 Spring 管理的 bean。