You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot事务服务暴露与方法调用时长度量(关注点分离)

无侵入式为应用服务添加事务与监控指标

核心思路

完全在Spring配置模块中通过动态代理+切面实现事务管理和Micrometer指标收集,不修改应用模块的任何代码,严格遵循关注点分离原则。


一、事务处理:基于Spring动态代理的声明式事务

通过Spring的BeanNameAutoProxyCreator结合TransactionInterceptor,为已注册的TagApplicationService Bean生成代理,注入事务逻辑,无需在应用类中添加Spring注解。

配置步骤:

  1. 注册应用服务Bean:
@Bean
public TagApplicationService tagApplicationService() {
    // 按需注入应用服务依赖(如Repository)
    return new TagApplicationService();
}
  1. 定义事务规则拦截器:
@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;
}
  1. 配置自动代理,为应用服务Bean添加事务拦截:
@Bean
public BeanNameAutoProxyCreator transactionProxyCreator() {
    BeanNameAutoProxyCreator proxyCreator = new BeanNameAutoProxyCreator();
    proxyCreator.setBeanNames("tagApplicationService");
    proxyCreator.setInterceptorNames("transactionInterceptor");
    return proxyCreator;
}

二、Micrometer指标收集:基于AOP切面的无侵入监控

利用Spring AOP和Micrometer的TimedInterceptor,通过切面匹配TagApplicationService的所有方法,自动收集调用时长指标,无需修改应用模块代码。

配置步骤:

  1. 定义监控拦截器:
@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;
}
  1. 配置切面,匹配应用服务的所有方法:
@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 09:07:36