动态代理的实现原理
要了解Spring的AOP就必须先了解动态代理的原理,因为AOP就是基于动态代理实现的。动态代理要从JDK本身说起。
在JDK的java.lang.reflect包下有个Proxy类,他正是构造代理类的入口。
该类有一个方法newProxyInstance就是创建代理对象的方法。
这个方法需要3个参数:ClassLoader,用来加载代理类的Loader类,通常这个Loader和被代理的类是同一个Loader类;Interfaces,是要被代理的那些接口;InvocationHandler,用于执行除了被代理接口中方法之外的用户自定义的操作,他也是用户需要代理的最终目的。用户调用目标方法都被代理到在InvocationHandler类中定义的唯一方法invoke()中。
下面还是看看Proxy产生代理类的过程,他构造的代理到底是什么样子?
其实从上图中可以发现,构造代理类是在ProxyGenerator的generateProxyClass方法中进行的。ProxyGenerator类在sun.misc包下。
Spring AOP如何实现
从代理的原理我们知道,代理的目的是调用目标方法时可以转而执行InvocationHandler类的invoke方法,所以如何在InvocationHandler上做文章就是Spring实现AOP的关键所在。
Spring的AOP实现遵守AOP联盟的约定,同时Spring又扩展了他,增加了如Pointcut、Advisor等一些接口使得其更加灵活。
Spring引用了Aop Alliance定义的接口。暂且不讨论Spring如何扩展Aop Alliance,先看看Spring是如何实现代理类的。要实现代理类,在Spring的配置文件中通常是这样定义一个Bean的:
<bean id="testBeanSingleton" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces" >
<value>org.springframework.aop.framework.PrototypeTargetTest$TestBean</value>
</property>
<property name="target">
<ref local="testBeanTarget"></ref>
</property>
<property name="singleton">
<value>true</value>
</property>
<property name="interceptorNames">
<list>
<value>testInterceptor</value>
<value>testInterceptor2</value>
</list>
</property>
</bean>
可以看到,要设置被代理的接口和接口的实现类(也就是目标类),以及拦截器(在执行目标方法之前被调用)。这里可以选择使用在Spring中定义的各种各样的拦截器。
下面看看Spring是如何完成代理的。
前面提到Spring AOP是实现其自身的扩展点来完成这个特性的,从这个代理类可以看出他继承了FactoryBean的ProxyFactoryBean,FactoryBean之所以特别就在于他可以让你自定义对象的创建方法。当然处理对象要通过Proxy类来动态生成。
下图是Spring创建代理对象的时序图。
在Spring创建了代理对象后,当你调用目标对象上的方法时,都会被代理到InvocationHandler类的invoke方法中执行,这在钱买你已经解释了。在这里JdkDynamicAopProxy类实现了InvocationHandler接口。
下面再看看Spring时如何调用拦截器的,下图是这个过程的时序图。
以上所说的都是JDK动态代理,Spring还支持一种CGLIB类代理。