切面编程遇到的注入service为null的问题分析

您所在的位置:网站首页 service注入service为null 切面编程遇到的注入service为null的问题分析

切面编程遇到的注入service为null的问题分析

2024-07-12 22:36| 来源: 网络整理| 查看: 265

切面编程遇到的注入service为null的问题分析 最近学习并运用了AOP切面编程,主要是在所有的controller方法中增加权限校验、时间统计。步骤如下: 1、引入依赖包 在这里插入图片描述

2、增加AOP配置类,并定义切入点@PointCut以及切入后要做的事情。 在这里插入图片描述

3、由于并不是controller中所有的api接口,需要进行权限校验,所以,我增加了一个自定义注解@CheckAuth,对controller下配有该注解的方法才进行权限校验。 在这里插入图片描述

3、增加了一个接口,进行了测试。 在这里插入图片描述

/testAop接口可以正常运行,以为就完成了。结果出现了问题,某些api接口中,通过@Autowired引入的service对象,出现了null的情况,导致接口异常。

原来,这个与Springboot的动态代理有关。Springboot默认cglib动态代理模式。动态代理是什么?Cglib又是怎么代理的?AOP切面编程跟cglib又有什么关联?

通俗地讲,代理proxy就像是代理人,代表他人办理事务,他人就是被代理人。如果被代理人固定为一个,就是静态代理,反之,就是动态代理。动态代理分为JDK动态代理和CGLIB动态代理。

JDK动态代理,是jre内部提供的,可以直接使用,最关键的两个词儿就是proxy、invoke,就是Proxy创建一个对象实例,实现InvocationHandler的invoke方法,同时InvocationHandler包含了被代理对象,就像是被代理对象的一个包装。如下图,Proxy代理了InvocationHandler,InvocationHandler代理了Target,两级代理,也是对象之间的代理。开发人员可在InvocationHandler的invoke()方法内部,写自己的代码,实现某些操作,即代码增强。

在这里插入图片描述

Ciglib动态代理,本质是使用了继承,并且子类重写父类的方法(方法名与父类方法一致)。最关键的词儿就是MethodInterceptor、intercept。B(代理类)继承了Target类、实现了MethodInterceptor,且子类B中有重写方法、cglib方法(名叫“CGLIB”+“ 父 类 方 法 名 父类方法名 父类方法名”的方法)、父类方法(不可见),还有一个统一的拦截方法(增强方法intercept)。其中重写方法和cglib方法是有映射关系的。Ciglib代理,就是通过这个intercept,去调用了ciglib方法,继而去调用代理类中的重写方法(因为invoke反射机制无法直接调用父类的方法)。我们可以在intercept方法中写增强代码。

AOP切面编程,默认就是用了ciglib的动态代理。其中代理类中的ciglib方法只能构建父类的非private方法,controller中的private对象和方法,是无法被动态代理继承的。所以AOP切入的controller中接口是必须要声明为public的。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3