Spring Aop代理不生效

  

项目场景:

要做一个切面记录请求参数和返回参数的日志


问题描述:

  在contrller层和service层做切面,没有什么问题。对工具类进行切面处理时,没有办法代理。


原因分析:

代理模式不生效的场景:

1,对静态方法不代理

2,对私有方法不代理

3,被代理的类如果不是由spring管理的话代理不生效,因为Spring AOP 的底层是依赖于IOC管理对应的bean

4,若是被代理的类,被增强的方法中内部调用了被增强的方法。第二个方法的代理也会失效

5,


解决方案:

通过跟踪spring的原码查看为什么被代理的对象已经被代理了,但是没有执行对应切面的增强方法;

1,首先定位到创建对应的代理对象代码,在IOC装载对应的bean时,会执行AbstractAutoProxyCreate的后置处理方法,生成对应的代理对象。

2,根据传入的beanName,扫描出该被代理对象有多少个增强方法,创建代理对象,放入缓存中;

3,查看返回的代理对象,通过debug模式,能看到生成的代理对象的切面包含我需要的增强方法,说明生成的代理对象没有问题;

4,查看代理对象的执行代理过程,CglibAopProxy的代理过程:如何把注册的增强方法执行的。

         4.1首先要了解Cglib的是如何生成何使用代理对象的;

               4.2 CglibAopProxy通过内部类DynamicAdvisedInterceptor的intercept执行代理方法;通过getInterceptorsAndDynamicInterceptionAdvice()获取拦截器链也就是我们在@Aspect切面中定义的前置,后置,环绕的增强方法;通过定位,发现我的AOP失效问题出现在获取拦截链问题上;对比了正常的拦截和异常拦截的两者的区别:

图一是正常的:可以获取到两个拦截器;

                                                                                                                            图一

                4.3进一步定位为什么没有扫描出所有的拦截链,DefaultAdvisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice()获取该被代理对象所有的切面方法;

              4.4越来越接近真相了,在遍历Advisor时确实有扫描到需要的增加类,但是为什么没有加入到对应的拦截链里?在DefaultAdvisorChainFactory

                4.5AspectJExpressionPointcut的matchs方法匹配是否有对应的增强方法,走到getTargetShadowMatch()获取ShadowMatch,获取该method方法是否有匹配的增强方法;

               4.6查看到AOP的底层实现首先生成的代理对象会扫描自己所有拥有的增加方法,即会有一个advice的集合,然后在获取当前的拦截链时,首先先获取obtainPointcutExpression切点的表达式,然后根据对应的切点进行匹配。

               4.7一路追踪,AOP在加载切面的时候,会讲匹配的方法先缓存起来。所以问题就出在匹配方法时无法匹配的问题。SignaturePattern 匹配模糊 ,ExactTypePattern 不匹配,不能匹配上对应的类型。也就是继承的类和子类无法匹配上。当调用父类的方法的时候,由于父类方法的路径和配置拦截的子类路径不一致,导致没有办法匹配上,所以导致切面失败。

           5.结论:AOP无法通过配置子类的表达式切父类的方法;

           6.解决方式:

            https://blog.csdn.net/zxx3536/article/details/109093876

参考文章:

  https://www.oschina.net/question/561986_2244468?sort=time

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值