切换数据源的注解失效--代理对象冲突

在使用@DataSource注解进行数据源切换时,发现无法正常工作。问题出在@Controller类上的@Transactional注解创建了一个代理对象,导致@DataSource被覆盖,进而影响了切面处理。解决方法是将@Transactional移到Service接口的方法上,以避免代理对象冲突并确保切面正确切入。

今天使用数据源切换注解@DataSource的时候,发现没能成功切换,就在切换数据源的切面类里打了个断点,发现根本没切进去

下面时自定义的切面类,用Aspectj做的

    @Pointcut("@annotation(com.skywell.common.annotation.DataSource)"
            + "|| @within(com.skywell.common.annotation.DataSource)")
    public void dsPointCut() {

    }

    @Around("dsPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        DataSource dataSource = getDataSource(point);

        if (StringUtils.isNotNull(dataSource)) {
            DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
        }

        try {
            return point.proceed();
        } finally {
            // 销毁数据源 在执行方法之后
            DynamicDataSourceContextHolder.clearDataSourceType();
        }
    }

 下面是我在serviceImpl上使用注解的代码

    @DataSource(value = DataSourceType.OA)
    @Override
    public String importData(List<HrOaPermanentUserDTO> hrOaPermanentUserDTOList) {
        return mapper.insert(hrOaPermanentUserDTOList)
    }

很奇怪,按照切入点表达式,是肯定能切进去,定义了@DataSource注解的方法和类都应该能切到,但是我偏偏没切到

@Pointcut("@annotation(com.skywell.common.annotation.DataSource)"
        + "|| @within(com.skywell.common.annotation.DataSource)")

 后来进过反复排查,发现原因是我在controller类上定义了@Transactional事务注解,导致了切面切不到

原因:controller上的@Transactional会生成一个代理对象,会包裹service实现类中的方法,而aspectj也是基于spring aop实现的,他生成的代理对象也会包裹service方法,这时就会导致代理对象冲突

但是由于@Transactional优先级高于其他注解,则导致@Transactional覆盖了@DataSource注解,使得@DataSource失效,也就导致不会走到切面类

解决方法:将@Transactional注解添加到Service接口中的方法上的方式,避免在Controller类上添加@Transactional注解,在Service实现类上添加@DataSource注解,这样可以避免代理对象的冲突,也可以保证切面类可以正确的切入到被切方法中。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值