技术开发 频道

Spring 框架的设计理念与设计模式分析

  Spring AOP 如何实现

  从前面代理的原理我们知道,代理的目的是调用目标方法时我们可以转而执行 InvocationHandler 类的 invoke 方法,所以如何在 InvocationHandler 上做文章就是 Spring 实现 Aop 的关键所在。

  Spring 的 Aop 实现是遵守 Aop 联盟的约定。同时 Spring 又扩展了它,增加了如 Pointcut、Advisor 等一些接口使得更加灵活。

  下面是 Jdk 动态代理的类图:

  图 18. Jdk 动态代理的类图

 Spring AOP 的实现

  上图清楚的显示了 Spring 引用了 Aop Alliance 定义的接口。姑且不讨论 Spring 如何扩展 Aop Alliance,先看看 Spring 如何实现代理类的,要实现代理类在 Spring 的配置文件中通常是这样定一个 Bean 的,如下:

  清单 9. 配置代理类 Bean

<bean id="testBeanSingleton"
    
class="org.springframework.aop.framework.ProxyFactoryBean">
    
<property name="proxyInterfaces">
        
<value>
            org.springframework.aop.framework.PrototypeTargetTests$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 创建的代理对象的时序图:

  图 19.Spring 代理对象的产生

 Spring AOP 的实现

  Spring 创建了代理对象后,当你调用目标对象上的方法时,将都会被代理到 InvocationHandler 类的 invoke 方法中执行,这在前面已经解释。在这里 JdkDynamicAopProxy 类实现了 InvocationHandler 接口。

  下面再看看 Spring 是如何调用拦截器的,下面是这个过程的时序图:

  图 20.Spring 调用拦截器

 Spring AOP 的实现

  以上所说的都是 Jdk 动态代理,Spring 还支持一种 CGLIB 类代理,感兴趣自己看吧。

0
相关文章