proxyfactorybean aop实现过程

我们首先来看一下使用Proxy 获取Bean对象的流程
在这里插入图片描述
1 对于代理工场类的Bean对象获取是通过 getObject 函数来创建对象的.通过 分析ProxyFactoryBean类来看下其AOP实现原理
在这里插入图片描述
2.调用初始化函数initializeAdvisorChain在这里插入图片描述
首先会通过一个boolean变量判断当前是否已经初始化过,如果有则返回
其次会判断我们XMLbean对象里面是否有拦截器interceptor(interceptorNames属性)
如果有,则对所有的拦截器名字通过getBean方法获取对象添加到advisor里面.需要注意的是,这里有对*判断处理的逻辑.如果某一个拦截器名字最后面一个字符是*.那么会到DefaultListableBeanFactory查找所有符合要求的bean对象,然后如果这些对象名是以拦截器*号之前的字符串开头的.则把它加入到拦截器List里面

3.addAdvisor在这里插入图片描述
这里的代码很简单,因为advisor是存放在List里面的.所以先获取List大小,然后存放在数组的最后面
5.addAdvisorInternal
在这里插入图片描述
advisors 声明:rivate List advisors = new ArrayList<>();
就是把对象增加进去.下面两个函数调用不用太关心
6.getSingletonInstance
因为ProxyFactoryBean是一个单例,所以会走getSingletonInstance这个分支
在这里插入图片描述
7.freshTargetSource
在这里插入图片描述
这里就很明显.就是根据我们设置的target属性来通过getBean获取对象.所以target设置在这个时候会被用到.
8.setInterfaces
这个函数是当我们获取了target对象后,查看class里面有哪些interface.因为一个class可以implements多个interface,然后都存放到List里面,代码截图如下在这里插入图片描述
9.createAopProxy.
这里就开始创建AOP代码对象了,截图如下
在这里插入图片描述
在这里有两种类型的代理,本篇只介绍JDK的代码使用invocationHandle.Cglib代理会在以后的另一扁里面讲.

10.getProxy在这里插入图片描述
这里很明显直接使用JDK代理生成代理对象返回给调用者.Proxy.newProxyInstance是JAVA 代理类Proxy代理类的接口调用,有兴趣的可以看JAVA源码Proxy类.它有三个参数,第一个就是加载器这个获取加载器是固定代码没什么说的.第二个就是接口类数据.在这里传进去的就是我们先前从target里面获取的interface数组.第三个就是invocationHandle接口的实现,它里面就一个方法invoke.当我们使用代码对象调用方法时,会首先到invoke函数中在.然后在invoke里面加上一些自己想要的代码加强,然后继续调用它原本的代码或者其它.所以想要理解spring JDK代理是如何实现AOP的就需要去看invoke方法是如何实现的.

INVOKE方法实现流程图
在这里插入图片描述
这个流程图还是比较复杂的,我也是看了差不多一二个星期.才差不多把这个AOP的过程搞清楚,还是从流程一步一步来说吧.
1.首先AOP代理对象调用函数,触发JDK代理的invoke方法.方法截图如下:
在这里插入图片描述
函数头部是一些过滤操作.首先根据method的方法名字,判断是否为equals或者hashcode如果是则调用本地实现的对应方法.再次则是判断method所在的枚举类是不是DecoratingProxy或者是interface且是advised类的父类
一般情况下函数调用基本不会触发以上操作.来看正常操作是如何实现AOP增加的,我从里只从MethodBeforeAdvice这个before增强来说,其它的都是类似的.

2.getInterceptorsAndDynamicInterceptionAdvice这个是关键函数函数,AOP的实现就看它的了,逻辑过程比较复杂还是从代码角度来说吧截图如下:
在这里插入图片描述
3.
在这里插入图片描述
Advisor[] advisors = config.getAdvisors();
这个函数调用就是获取先前初始化的时候,注册的拦截器.
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
这个class就是target的class,下面那个if else match的大体意思就是说,从这个class中查找调用的method,一般情况下match都应该为true.除非你胡搞且保证编译通过.
当match为true的时候,也就是说这个method方法是class类里面拥有的成员函数.那么接下来就是对注册的所有的拦截器调用一一registry.getInterceptors(advisor);处理将生成的LIST加入到总的List队列中去interceptorList.来看下registry.getInterceptors的实现在这里插入图片描述
请知道一点,我们注册的拦截器通过getBean生成的对象在加入拦截器List之前会调用wrap进行一层封装,就是上面的那个wrap函数.在getInterceptors函数处理的时候首先会调用 Advice advice = advisor.getAdvice();方法拿到getBean生成的原生对象,然后对象对象类型判断它是哪一类拦截器.这里我们只看before拦截器.首先拦截器类型应该只有三类在这里插入图片描述
看beforeAdapter的实现在这里插入图片描述
再看adviceInterceptor的实现在这里插入图片描述
看到没这里有invoke有个before增强调用.好了到这里已经拿到增强类的拦截器了.返回到JDK类最开始调用的地方getInterceptorsAndDynamicInterceptionAdvice截图:
在这里插入图片描述
我们已经拿到所有的拦截器,那么这里chain显示不为空如何我们有注册拦截器.会走到else,这里会生成一个ReflectiveMethodInvocation对象把拦截器LIST作参数传进去看类的构造函数在这里插入图片描述
我们的拦截器都被赋值给了interceptorsAndDynamicMethodMatchers变量.
创建完对像后,直接调用了这个类的proceed函数
在这里插入图片描述
currentInterceptorIndex默认为-1.++currentInterceptorIndex也就是从0开始从List里面取出拦截器对象.然后调用dm.interceptor.invoke(this);来调用增强接口,注意这里传递的参数为this,这个非常重要.我们以beforeAdapter为例来说明:在这里插入图片描述
这里调用就是beforeInterceptor的invoke接口.advice就是我们生成MethodBeforeAdviceInterceptor时传递的getBean对象这点上面已经说过.好了增强的before调用了,然后就是mi.proceed这个mi就是我们传进来的this对象.就是ReflectiveMethodInvocation本身.也就是说这是一个递归调用.每调用一次currentInterceptorIndex就自加1当currentInterceptorIndex增大到为拦截器总数量时才会调用我们本身想调用的method
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
函数invokeJoinpoint();就是实现我们原本想调用的方法,就不再跟下去了.到这里JDK的动态代理实现AOP的流程就说完了.欢迎大家纠正存在的问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bruk_spp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值