我正在使用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()
配置,注册表和原型虚拟bean都是正确的。
我正在使用现有的集成测试来测试流程,并且在那里没有提供原型Bean,而是使用new
关键字实例化了DummyService的新对象。它不是Spring管理的Bean。
Spring AOP仅适用于Spring托管的bean。