JdkDynamicAopProxy-invoke方法-5

来源:互联网 发布:windows xp下 arp命令 编辑:程序博客网 时间:2024/06/03 21:34

通过前面例子jdk动态代理生成代理对象的源码分析,已经可以很清楚的了解到代理对象是如何进行增强和回调的,接下来继续分析JdkDynamicAopProxy是如何进行回调的对目标对象进行增强的。同样,在JdkDynamicAopProxy中实现也了InvocationHandler接口中的invoke方法。在JdkDynamicAopProxy中生成代理对象时,通过调用Proxy.newProxyInstance(classLoader,proxiedInterfaces,this);方法来生成代理对象,这里的this参数对应的是InvocationHandler对象,InvocationHandler是JDK定义的反射类的一个接口,这个接口定义了invoke方法,而这个invoke方法是作为JDK Proxy代理对象进行拦截的回调入口出现的。在JdkDynamicAopProxy中实现了InvocationHandler接口,也就是当Proxy对象的代理方法被调用时,JdkDynamicAopProxy的的invoke方法作为Proxy对象的回调函数被触发,从而通过invoke的具体实现,来完成对目标对象方法调用的拦截或者说功能的增强工作。JdkDynamicaopProxy的invoke方法代码清单如下。从代码清单中可以看出,对Proxy对象的代理设置是在invoke方法中完成的,这些设置包括获取目标对象、拦截器链,同时把这些对象作为输入,创建了ReflectiveMethodInvocation对象,通过这个ReflectiveMethodInvocation对象来完成对Aop功能实现的封装。在这个invoke方法中,包含了一个完整的拦截器链对目标对象的拦截过程,比如获得拦截器链并对拦截器链中的拦截器进行了配置,逐个运行拦截器链里的拦截器增强,直到最后对目标对象方法的运行等。

JdkDynamicAopProxy代理对象的回调主要代码

 

 

invoke方法中,核心内容是获取拦截器链,如果拦截器链为空,则直接调用目标方法,如果拦截器链不为空则先调用拦截器链,再对目标方法进行调用。

首先是获得拦截器链,从List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);方法中,可以看出获取interceptors的操作是由advised对象完成的,

这个advised 是一个AdvisedSupport对象,从类的继承上来看,这个AdvisedSupport类同时也是ProxyFactoryBean的基类。从AdvisedSupport的代码中可以看到getInterceptorsAndDynamicInterceptionAdvice的实现,代码清单如下。在这个方法中获得了拦截器链,在取得拦截器链的时候,为提高取得拦截器的效率,还为其设置了缓存。

AdvisedSupport类中getInterceptorsAndDynamicInterceptionAdvice方法

 

 

这里使用了cache,利用cache去获取已有的inteceptor链,但是第一次还是需要自己动手生成。这个interceptor链的生成是由advisorChainFactory完成的,这里使用的是DefaultAdvisoChainFactory。在DefaultAdvisorChainFactory中实现了一个interceptor链的获取过程,代码如下。

DefaultAdvisorChainFactory类中getInterceptorsAndDynamicInterceptionAdvice方法

 


 

 

在这个获取过程中,首先设置了一个list,其长度是由配置的通知器的个数来决定的,这个配置就是在XML中对ProxyFactoryBean做的interceptorNames属性的配置。然后DefaultAdvisorChainFactory会通过一个AdvisorAdapterRegistry来实现拦截器的注册,AdvisorAdapterRegistryadvice通知的织入功能起了很大的作用。有了AdvisorAdapterRegistry注册器,利用它来对从ProxyFactoryBean配置中得到的通知进行适配,从而获得相应的拦截器,再把他加入到前面设置好的List中去,完成所谓的拦截器注册过程

。在拦截器适配和注册过程完成以后,list中的拦截器会被JDK生成的AopProxy代理对象的invoke方法或者CGLIB代理对象的interceptor拦截方法取得,并启动拦截器的invoke调动,最终触发通知的切面增强。前面在3-ProxyFactoryBean生成AopProxy代理对象已经对拦截器进行了注册,这里可以直接通过interceptors1 = registry.getInterceptors(advisor);获取拦截器对象进行匹配。具体获取代码如下。

DefaultAdvisorAdapterRegistry类中getInterceptors方法

 

 

到目前为止,已经完成了对第1点的调用,并且已经获取到了拦截器。

接下来判断是否存在拦截器链,如果拦截器链不存在,则会直接调用,代码如下:

 

到这里已经完成对第2点的解析。如果在拦截器链存在的情况下,接着会进入到第34invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();对拦截器和目标方法进行调用,首先是实例化一个ReflectiveMethodInvocation对象,并传递代理对象,目标对象,目标方法,参数,目标class类以及拦截器链,接着再在该类中对拦截器链进行调用,具体代码如下:

ReflectiveMethodInvocation

 

 

 

process方法中,首先判断拦截器链是否已经调用完毕,如果已经调用完毕,则对目标方法进行调用,如果没有调用完毕则递归调用proceed方法。

 

在网上找了一篇差不多比较详细的,可以仔细看看http://www.docin.com/p-1529480972.html