Spring AOP不能切入类内部调用的方法 分析测试

类中有两个方法都有切面,如果在一个有切面的方法中,用this.调用另一个有切面的方法,会使被调用方法aop失效.

因为aop是基于接口或者是基于类创建代理,而不是基于方法创建代理

this指的是当前对象,当前对象是类,而不是代理类.

不想失效,就把类本身注入进类里,通过ioc容器调用类,这样就能生成代理类,就不会失效了

 

因为事务是用aop动态代理实现的,我们就测试一下事务失效的例子.

public interface AnalysisService {
  
     void deleteAnalysisRole(int analysisRuleId);

     void deleteAnalysisParam(int analysisRuleId);

}


@Service
public class AnalysisServiceImpl implements AnalysisService {
    @Autowired
    private AnalysisMapper analysisMapper;
    @Autowired
    private AnalysisService analysisService;
   

    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteAnalysisRole(int analysisRuleId) {
  
    //测试1  analysisService.deleteAnalysisParam(analysisRuleId);
    //测试2  this.deleteAnalysisParam(analysisRuleId);
       analysisMapper.deleteAnalysisRole(analysisRuleId);

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void deleteAnalysisParam(int analysisRuleId) {

        analysisMapper.deleteAnalysisParameter(analysisRuleId);

    }
}

实现类中的deleteAnalysisRole方法用于删除解析器与其参数( 解析器与解析器参数是两张表),

原方法删除解析器和其参数是在一个事务里,要么同时成功要么回滚.

但为了测试,把删除解析器与删除参数写在两个方法里,而且删除参数这个方法单独开一个事务(Propagation.REQUIRES_NEW 新建一个事务).

为了验证this.调用有切面的方法会不会失效,想了下边一个测试方法:

1 对照组: 

  • 流程:

解注测试1, 即用注入的service来调用删除参数的方法

analysisMapper.deleteAnalysisRole(analysisRuleId) 的sql里写错,让程序产生runtime异常,事务回滚,

用controller层调用service执行删除.

  • 结果:

参数表对应的行删除成功,解析器表对应的行删除失败.

  • 分析:

aop拦截了用注入的接口调用实现类的删除参数方法,删除参数方法是一个新建的事务,事务成功提交.

而删除规则的方法由于产生异常,事务回滚,删除失败.

2 实验组:

  • 流程:

解注测试2,用this来调用本类删除参数方法

analysisMapper.deleteAnalysisRole(analysisRuleId) 的sql里写错,让程序产生runtime异常,事务回滚,

用controller层调用service执行删除.

注意:

  • 结果:

参数表和解析器表都删除失败.

  • 分析

是因为this是当前对象.删除参数是类调用的方法,aop没有切入内部调用的方法,没有生成动态代理类

没有生成代理类就没有实现事务,导致删除参数方法不能新建事务,于是加入了调用方法的事务中,随着异常一块回滚.

注意:

1.删除参数方法要写在删除规则前面,如果写在后面,运行时因为规则抛出异常,运行不到删除参数就会回滚,导致测试没有意义.

2.如果注入的是实现类自己

@Autowired
 private AnalysisServiceImpl analysisServiceImpl;

也不会导致aop失效,注入自己也生成了代理类.

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值