不知道读者是否还记得,前面的章节中,我们学习了Spring是如何去获得增强方法或增强器,那么这一节中,我们主要来看看Spring是怎样去创建代理。首先我们来看一下创建代理的时序图。
1. AbstractAutoProxyCreator
在获取了对应的bean之后,便可以进行代理的创建了。
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
//获取当前类中相关属性
proxyFactory.copyFrom(this);
//决定对于给定的bean是否应该使用targetClass而不是他的接口代理
//检查 proxyTargeClass设置及preserveTargetClass属性
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
//添加代理接口
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
//加入增强器
proxyFactory.addAdvisor(advisor);
}
//设置要代理的类
proxyFactory.setTargetSource(targetSource);
//定制代理
customizeProxyFactory(proxyFactory);
//用来控制代理工厂被配置之后,是否允许修改通知
//缺省值为false(即在代理被配置之后,不允许修改代理的配置)
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.<strong>getProxy(getProxyClassLoader())</strong>;
}
2. ProxyFactory
Sprin在创建代理的时候,又将功能委托给了ProxyFactory的类,所在在ProxyFactory的类中可以看到方法getProxy().
public Object getProxy(ClassLoader classLoader) {
return <strong>createAopProxy()</strong>.getProxy(classLoader);
}
如果笔者进一步跟踪createAopProxy().getProxy(classLoader)的getProxy()的方法,我们将看到,这里将分为JDK代理的CGLIB的代理 。如下图所示。
3. ProxyCreatorSupport
接下来,我们跟踪代码进入createAopProxy().getProxy(classLoader)的createAopProxy()的方法里,该方法在ProxyCreatorSupport中被定义。
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
//创建代理
return getAopProxyFactory().<strong>createAopProxy(this</strong>);
}
4. DefaultAopProxyFactory
在上面的方法中,我们可以看,Srping又把方法委托给了DefaultAopProxyFactory的类去处理了。我们继续进入getAopProxyFactory().createAopProxy(this)的createAopProxy的方法内,可以看到真正创建代理的代码。
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (<strong>config.isOptimize()</strong> || <strong>config.isProxyTargetClass()</strong> || <strong>hasNoUserSuppliedProxyInterfaces(config)</strong>) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
5. 总结
对于创建代理,我们可以归结为以下几点:
1) 获取当前类中的属性
2) 添加代理接口
3) 封装Advisor并加入到ProxyFactory中
4) 设置要代理的类
5) 当然在Spring中还为子类提供了定制的函数customizeProxyFactory,子类可以在此函数中进行对ProxyFactory的进一步封装。
6) 进行获取代理操作