这是我参与更文挑战的第15天,活动详情查看:更文挑战
看清ProxyFactory的本质
要了解ProxyFactory,我们得先从它的“根”说起,即org.springframework.aop.framework.AopProxy,该接口定义如下:
public interface AopProxy {
Object getProxy();
Object getProxy(ClassLoader classLoader);
}
复制代码
Spring AOP框架内使用AopProxy对使用的不同的代理实现机制进行了适度的抽象,针对不同的代理实现机制提供相应的AopProxy子类实现。目前,Spring AOP框架内提供了针对JDK的动态代理和CGLIB两种机制的AopProxy实现,如下图所示:
当前,AopProxy有Cglib2AopProxy和JdkDynamicAopProxy两种实现。因为动态代理需要通过InvocationHandler提供调用拦截,所以,JdkDynamicAopProxy同时实现了InvocationHandler接口。不同AopProxy实现的实例化过程采用抽象工厂模式进行封装。即通过org.springframework.aop.framework.AopProxyFactory进行。AopProxyFactory接口的定义如下所示:
public interface AopProxyFactory {
AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;
}
复制代码
AopProxyFactory根据传入的AdvisedSupport实例提供的相关信息,来决定生成什么类型的AopProxy。不过,具体工作会转交给AopProxyFactory的具体实现类。而实际上这个AopProxyFactory实现类现在就一个,即org.springframework.aop.framework.DefaultAopProxyFactory。DefaultAopProxyFactory的实现逻辑很简单,伪代码如下:
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyFactory(config)){
//创建Cglib2AopProxy实例,并返回
}else {
//创建JdkDynamicAopProxy实例,并返回
}
复制代码
也就是说,如果传入的AdvisedSupport实例config的isOptimize或者isProxyTargetClass方法返回true,或者目标对象没有实现任何接口,则采用CGLIB生成代理对象,否则使用动态代理。
AopProxyFactory需要根据createAopProxy方法传入的AdvisedSupport实例信息,来构建相应的AopProxy。下面我们来看看这个AdvisedSupport到底是何方神圣。
说的简单一点,AdvisedSupport其实就是一个生成代理对象所需要的信息的载体,该类相关的类层次图,如下图所示:
AdvisedSupport所承载的信息可以划分为两类,一类以org.springframework.aop.framework.ProxyConfig为统领,记载生成代理对象的控制信息;一类以org.springframework.aop.framework.Advised为旗帜,承载生成代理对象所需要的必要信息,如相关目标类、Advice、Advisor等。
ProxyConfig其实就是一个普通的JavaBean,它定义了5个boolean型的属性,分别控制在生成代理对象的时候,应该采取哪些行为措施,5个属性分别是:1.proxyTargetClass 2.optimize 3.opaque 4.exposeProxy 5.frozen
要生成代理对象,只有ProxyConfig提供的控制信息还不够,我们还需要生成代理对象的一些具体信息,比如,要针对哪些目标类生成代理对象,要为代理对象加入何种横切逻辑等,这些信息可以通过org.springframework.aop.framework.Advised设置或者查询。默认情况下,Spring AOP框架返回的代理对象都可以强制转型为Advised,以查询代理对象的相关信息。
回到之前的AdvisedSupport话题,AdvisedSupport继承了ProxyConfig,我们可以通过AdvisedSupport设置代理对象生成的一些控制属性。AdvisedSupport同时实现了Advised接口,我们也可以通过AdvisedSupport设置生成代理对象相关的目标类、Advice等必要信息。这样,具体的AopProxy实现在生成代理对象时,可以从AdvisedSupport这里取得所有这些必要信息。
现在回到主题ProxyFactory。AopProxy、AdvisedSupport与ProxyFactory是什么关系呢?见下图:
ProxyFactory集AopProxy和AdvisedSupport于一身,所以,可以通过ProxyFactory设置生成代理对象所需要的相关信息,也可以通过ProxyFactory取得最终生成的代理对象。前者是AdvisedSupport的职责,后者是AopProxy的职责。
ProxyFactoryBean
虽然使用ProxyFactory,可以让我们能够独立于Spring的IoC容器之外来使用Spring的AOP支持,但是,将Spring AOP与Spring IoC的容器相结合,才是发挥Spring AOP更大作用的最佳途径。通过结合Spring的IoC容器,我们可以在容器中对Pointcut和Advice等进行管理,即使他们依赖于其他业务对象,也可以很容易地注入其中。
在IoC容器中,使用org.springframework.aop.framework.ProxyFactoryBean作为织入器,它的使用与ProxyFactory无太大差别。
待补