SpringBoot事务服务暴露与方法调用时长度量(关注点分离)
无侵入式为应用服务添加事务与监控指标
核心思路
完全在Spring配置模块中通过动态代理+切面实现事务管理和Micrometer指标收集,不修改应用模块的任何代码,严格遵循关注点分离原则。
一、事务处理:基于Spring动态代理的声明式事务
通过Spring的BeanNameAutoProxyCreator结合TransactionInterceptor,为已注册的TagApplicationService Bean生成代理,注入事务逻辑,无需在应用类中添加Spring注解。
配置步骤:
- 注册应用服务Bean:
@Bean public TagApplicationService tagApplicationService() { // 按需注入应用服务依赖(如Repository) return new TagApplicationService(); }
- 定义事务规则拦截器:
@Bean public TransactionInterceptor transactionInterceptor(PlatformTransactionManager txManager) { Properties txProps = new Properties(); // 为create开头的方法配置REQUIRED事务 txProps.setProperty("create*", "PROPAGATION_REQUIRED"); // 为get开头的方法配置只读SUPPORTS事务 txProps.setProperty("get*", "PROPAGATION_SUPPORTS,readOnly"); TransactionInterceptor interceptor = new TransactionInterceptor(); interceptor.setTransactionAttributes(txProps); interceptor.setTransactionManager(txManager); return interceptor; }
- 配置自动代理,为应用服务Bean添加事务拦截:
@Bean public BeanNameAutoProxyCreator transactionProxyCreator() { BeanNameAutoProxyCreator proxyCreator = new BeanNameAutoProxyCreator(); proxyCreator.setBeanNames("tagApplicationService"); proxyCreator.setInterceptorNames("transactionInterceptor"); return proxyCreator; }
二、Micrometer指标收集:基于AOP切面的无侵入监控
利用Spring AOP和Micrometer的TimedInterceptor,通过切面匹配TagApplicationService的所有方法,自动收集调用时长指标,无需修改应用模块代码。
配置步骤:
- 定义监控拦截器:
@Bean public TimedInterceptor timedInterceptor(MeterRegistry meterRegistry) { TimedInterceptor interceptor = new TimedInterceptor(meterRegistry); interceptor.setMetricName("tag.application.service.method.duration"); interceptor.setDescription("Execution duration of TagApplicationService methods"); // 添加方法名标签,便于区分不同方法的指标 interceptor.setTagProvider((method, args) -> Collections.singletonMap("method", method.getName())); return interceptor; }
- 配置切面,匹配应用服务的所有方法:
@Bean public Advisor timedAdvisor(TimedInterceptor timedInterceptor) { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); // 匹配TagApplicationService的所有公共方法 pointcut.setExpression("execution(public * application.tag.TagApplicationService.*(..))"); return new DefaultPointcutAdvisor(pointcut, timedInterceptor); }
三、完整整合配置
将事务和监控配置整合到同一个配置类中,开启必要的Spring注解:
@Configuration @EnableTransactionManagement @EnableAspectJAutoProxy class ApplicationConfiguration { // 注册应用服务Bean @Bean public TagApplicationService tagApplicationService() { return new TagApplicationService(); } // 事务拦截器 @Bean public TransactionInterceptor transactionInterceptor(PlatformTransactionManager txManager) { Properties txProps = new Properties(); txProps.setProperty("create*", "PROPAGATION_REQUIRED"); txProps.setProperty("get*", "PROPAGATION_SUPPORTS,readOnly"); TransactionInterceptor interceptor = new TransactionInterceptor(); interceptor.setTransactionAttributes(txProps); interceptor.setTransactionManager(txManager); return interceptor; } // 事务自动代理 @Bean public BeanNameAutoProxyCreator transactionProxyCreator() { BeanNameAutoProxyCreator proxyCreator = new BeanNameAutoProxyCreator(); proxyCreator.setBeanNames("tagApplicationService"); proxyCreator.setInterceptorNames("transactionInterceptor"); return proxyCreator; } // Micrometer监控拦截器 @Bean public TimedInterceptor timedInterceptor(MeterRegistry meterRegistry) { TimedInterceptor interceptor = new TimedInterceptor(meterRegistry); interceptor.setMetricName("tag.application.service.method.duration"); interceptor.setDescription("Execution duration of TagApplicationService methods"); interceptor.setTagProvider((method, args) -> Collections.singletonMap("method", method.getName())); return interceptor; } // 监控切面 @Bean public Advisor timedAdvisor(TimedInterceptor timedInterceptor) { AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(); pointcut.setExpression("execution(public * application.tag.TagApplicationService.*(..))"); return new DefaultPointcutAdvisor(pointcut, timedInterceptor); } }
方案优势
- 严格遵循关注点分离:应用模块仅负责业务逻辑,事务、监控等基础设施逻辑完全隔离在Spring配置模块中。
- 无侵入:无需修改应用模块代码,避免了继承带来的紧耦合和代码冗余。
- 职责清晰:事务和监控通过独立的代理/切面实现,可单独调整配置,互不干扰。
内容的提问来源于stack exchange,提问作者marcin.ciapa
相关产品推荐
相关产品推荐

