Spring源码之创建代理

不知道读者是否还记得,前面的章节中,我们学习了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)        进行获取代理操作




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值