关于spring aop对接口方法上的注解无法拦截问题

最近实现一个功能,在访问dao层方法前需要切换数据源,通过自定义注解+AOP实现:AOP中拦截被注解的方法,实现数据源切换。Dao层用mybatis实现,注解加在Mapper接口中的方法上。但是AOP无法对加了自定义注解的方法进行拦截。由此做了以下总结:

一、关于注解继承问题

对于接口,在接口中的注解无论如何都不能被继承,不论是子接口继承父接口的情况还是接口的实现类的情况,不论是对接口上还是接口中的方法上的注解,都不能,以上经过测试所得。

对于类,注解上使用@Inherited标注,类上的注解可以被继承。 @Inherited表示该类上的注解可以被注解,与方法上的注解的继承性无关。

对于类中方法上的注解,若子类覆写了父类带注解方法,从子类无法获取到注解。子类未覆写父类带注解方法,可以通过子类获得注解。与注解是否标注@Inherited无关。

其实,注解在方法中,没有所谓继承问题,只有重写问题。如果注解在父类方法中,如果方法没有被子类重写,那么调用的是父类的方法,那么注解是存在的,如果方法被子类重写,子类方法没有注解,那么调用子类方法就获取不了注解

二、关于在接口的方法中加注解作为拦截点,拦截失败的原因:

1、AOP使用jdk动态代理的情况

接口中的注解无法被实现类继承,AOP中的切点无法匹配上实现类,所以并不会为实现类创建代理(根据是否被满足注解条件来判断是否创建代理,标红部分经过测试所得),所以我们使用的还是原始的未被代理的对象,所以就不会被拦截到了。

2、AOP使用cglib动态代理的情况

在不存在切点注解继承的情况,AOP可进行有效拦截(cglib动态代理)。但是考虑以下存在注解继承的情况

有类Parent,类Sub,Sub继承自Parent。根据注解的继承原则,切点注解在父类方法,

若Sub覆写了父类所有带注解方法,实际Sub中并未被AOP标识,所有spring并不会为Sub创建代理类,也就不会被拦截。

若Sub覆写了父类部分带注解方法,spring会为Sub创建代理类,对于覆写了父类的方法,由于注解未被继承,不会被拦截;未覆写的方法,可以被拦截。

所以,对于我遇到的问题:在mybatis中,加在Mapper接口方法上的注解无法被拦截可以做以下解释

mybatis本身会使用jdk动态代理来为我们生成一个Mapper接口的实现类,实际上我们的aop是在对这个Mapper的实现类创建代理(使用cglib代理)。由注解继承规则,该实现类的方法并不能继承接口方法上的注解,因而spring也就无法为该实现类生成代理,aop也就拦截失败。


  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值