Spring AOP的实现之建立AopProxy代理对象

          在Spring的AOP模块中,一个主要的部分是代理对象的生成,而对于Spring应用,可以看到,是通过配置和调用ProxyFactoryBean来完成这个任务的。

在ProxyFactoryBean中,封装了主要代理对象的生成过程。在生成过程可以使用两种方法,一种是JDK的Proxy,另一种是CGLIB。

         以ProxyFactory的设计为中心,可以看到相关的类继承关系。

        

         ProxyConfig作为共同的基类,它为各种子类提供了配置属性。

         AdvisorSupport的实现中,封装了AOP对通知和通知器的相关操作,这些操作对于不同的AOP的代理对象的生成都是一样的,但

对于具体的AOP代理对象的创建,AdvisorSupport把它交给它的子类去完成。

         ProxyCreatorSupport,可以将它看成是其子类创建AOP代理对象的辅助类。

         具体AOP代理对象的生成,根据不同的需要,分别由AspectProxyFactory、ProxyFactory、ProxyFactoryBean来完成。

         对于需要使用AspectJ的AOP应用,AspectProxyFactory起到Spring和AspectJ的集成。

         ProxyFactoryBean,可以在IoC容器中完成声明式的配置。

         ProxyFactory需要编程地使用Spring AOP的功能。

下面详细介绍从配置ProxyFactoryBean开始到具体的代理对象生成。

基于XML配置Spring

    <bean id="testAdvisor" class="com.abc.TestAdvisor"/>
    <bean id="testAOP" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="proxyInterfaces">
            <value>com.test.AbcInterface</value>
        </property>
        <property name="target">
            <bean class="com.abc.TestTarget"/>
        </property>
        <property name="interceptorNames">
            <list>
                <value>testAdvisor</value>
            </list>
        </property>
    </bean>
     (1)定义使用的通知器Advisor,这个通知器应该作为一个Bean来定义。这个通知器的实现定义了需要对目标对象进行增强的切面

行为,也就是Advice通知。

      (2)定义ProxyFactoryBean,把它作为另一个bean来定义,它是封装AOP功能的主要类。在配置ProxyFactoryBean需要配置与其相关的属性:

               interceptorNames属性的值往往设置为需要定义的通知器。这些通知器在ProxyFactoryBean配置下,是通过使用代理对象的拦截器机制起作用的。

               作为target属性注入的bean,是需要用AOP通知器中的切面应用来增强的对象。


ProxyFactoryBean生成AopProxy代理对象

          ProxyFactoryBean的AOP实现需要依赖JDK或者CGLIB提供的Proxy特性。从FactoryBean中获取对象,是以getObject方法作为入口完成的;

ProxyFactoryBean实现中的getObject方法,是FactoryBean需要实现的接口。对ProxyFactoryBean来说,把需要对target目标对象增加的增强处理,都通过

getObject方法进行封装了,这些增强处理是为AOP功能的实现提供服务的。

         ProxyFactoryBean类中的getObject方法

	@Override
	public Object getObject() throws BeansException {
		initializeAdvisorChain();//初始化通知器链,为Proxy代理对象配置Advisor链是在这个方法中完成的
                //这里对singleton和prototyope的类型进行区分,生成对应的proxy
                if (isSingleton()) {
			return getSingletonInstance();
		}
		else {
			if (this.targetName == null) {
				logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
						"Enable prototype proxies by setting the 'targetName' property.");
			}
			return newPrototypeInstance();
		}
	}
         ProxyFactoryBean中的initialzeAdvisorChain方法

        

	private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
		if (this.advisorChainInitialized) {//这是一个标志位,用来表示通知器链是否已经初始化。如果初始化,这里就不再初始化,而是直接返回。
			return;                    //也就是说初始化的工作发生在应用第一次通过ProxyFactoryBean去获取代理对象的时候。
		}

		if (!ObjectUtils.isEmpty(this.interceptorNames)) {
			if (this.beanFactory == null) {
				throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
						"- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
			}

			if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&	this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
 				throw new AopConfigException("Target required after globals");
 			}

                        //这里是添加Advisor链的调用,是通过interceptorNames属性进行配置的
  			for (String name : this.interceptorNames) {
 				if (logger.isTraceEnabled()) {
					logger.trace("Configuring advisor or advice '" + name + "'");
				}

 				if (name.endsWith(GLOBAL_SUFFIX)) {
 					if (!(this.beanFactory instanceof ListableBeanFactory)) {
						 throw new AopConfigException(
								 "Can only use global advisors or interceptors with a ListableBeanFactory");
 					}
					 addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
							 name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
				 }

				else {
					// 如果程序在这里被调用,那么需要加入命名的拦截器advice,并且需要检查这个Bean
					// 是singleton还是prototype类型
 					Object advice;
 					if (this.singleton || this.beanFactory.isSingleton(name)) {
 						// 添加advice或者advisor
						advice = this.beanFactory.getBean(name);
 					}
					else {
						// 对prototype类型Bean的处理
						advice = new PrototypePlaceholderAdvisor(name);
					}
					addAdvisorOnChainCreation(advice, name);
				}
			} 
		}

		this.advisorChainInitialized = true;
	}
            生成singleton的代理对象是在getSingletonInstance()完成的,这个方法是ProxyFactoryBean生成AopProxy代理对象的调用入口。

             代理对象会封装对target目标对象的调用,也就是说针对target对象的方法调用会被这里生成的代理对象所拦截。getSingletonInstance方法的具体实现为:

           

	private synchronized Object getSingletonInstance() {
		if (this.singletonInstance == null) {
			this.targetSource = freshTargetSource();//首先读取ProxyFactoryBean中的配置
			if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
                                //根据AOP框架来判断需要代理的接口
				Class<?> targetClass = getTargetClass();
				if (targetClass == null) {
					throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
				}
                                //这里设置代理对象的接口
                                setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
			}
			super.setFrozen(this.freezeProxy);
			 this.singletonInstance = getProxy(createAopProxy());//使用ProxyFactory来生成需要的Proxy
		}
		return this.singletonInstance;
	}
        protected Object getProxy(AopProxy aopProxy) {
             return aopProxy.getProxy(this.proxyClassLoader);
        } 
        具体代理对象的生成,是在ProxyCreatorSupport的基类AdvisedSupport的实现中借助AopProxyFactory完成的。因为ProxyFactoryBean本身就是AdvisedSupport的

子类,所以在ProxyFactoryBean中取得AopProxy是很方便的,而具体的AopProxy是通过AopProxyFactory来生成的。

        createProxy()方法是ProxyCreatorSupport类中实现的:

       

	protected final synchronized AopProxy createAopProxy() {
		if (!this.active) {
			activate();
		}
                //通过AopProxyFactory来创建AopProxy,AopProxyFactory是在初始化函数中定义的,使用的是DefaultAopProxyFactory
                return getAopProxyFactory().createAopProxy(this);
	}
         所以在DefaultAopProxyFactory中有createAopProxy方法

         

	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			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()) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}
在这个方法中将会进行对targetClass进行判断,如果是接口类,便使用JDK来生成Proxy;如果不是接口类,那么使用CGLIB来生成。

      在AopProxy代理对象的生成过程中,首先要从AdvisedSupport对象中取得配置的目标对象,这个目标对象是实现AOP功能所必需的。


AopProxy代理对象可以由JDK或CGLIB来生成,而JdkDynamicAopProxy和CglibAopProxy的实现都是通过AopProxy接口。

JDK生成AopProxy代理对象

     

	@Override
	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
		}
		Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

CGLIB生成AopProxy代理对象

	public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
		}

		try {
			Class<?> rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

			Class<?> proxySuperClass = rootClass;
			if (ClassUtils.isCglibProxyClass(rootClass)) {
				proxySuperClass = rootClass.getSuperclass();
				Class<?>[] additionalInterfaces = rootClass.getInterfaces();
				for (Class<?> additionalInterface : additionalInterfaces) {
					this.advised.addInterface(additionalInterface);
				}
			}

			// Validate the class, writing log messages as necessary.
			validateClassIfNecessary(proxySuperClass);

			// Configure CGLIB Enhancer...
			Enhancer enhancer = createEnhancer();
			if (classLoader != null) {
				enhancer.setClassLoader(classLoader);
				if (classLoader instanceof SmartClassLoader &&
						((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
					enhancer.setUseCache(false);
				}
			}
			enhancer.setSuperclass(proxySuperClass);
			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
			enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));

			Callback[] callbacks = getCallbacks(rootClass);
			Class<?>[] types = new Class<?>[callbacks.length];
			for (int x = 0; x < types.length; x++) {
				types[x] = callbacks[x].getClass();
			}
			// fixedInterceptorMap only populated at this point, after getCallbacks call above
			enhancer.setCallbackFilter(new ProxyCallbackFilter(
					this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
			enhancer.setCallbackTypes(types);

			// Generate the proxy class and create a proxy instance.
			return createProxyClassAndInstance(enhancer, callbacks);
		}
		catch (CodeGenerationException ex) {
			throw new AopConfigException("Could not generate CGLIB subclass of class [" +
					this.advised.getTargetClass() + "]: " +
					"Common causes of this problem include using a final class or a non-visible class",
					ex);
		}
		catch (IllegalArgumentException ex) {
			throw new AopConfigException("Could not generate CGLIB subclass of class [" +
					this.advised.getTargetClass() + "]: " +
					"Common causes of this problem include using a final class or a non-visible class",
					ex);
		}
		catch (Exception ex) {
			// TargetSource.getTarget() failed
			throw new AopConfigException("Unexpected AOP exception", ex);
		}
	}

这样,通过使用AopProxy对象封装target目标对象之后,ProxyFactoryBean的getObject方法得到的对象就不是一个普通的java对象,而是一个AopProxy代理对象。

在ProxyFactoryBean中配置的target目标对象,已经不会让应用直接调用其方法实现,而是作为AOP实现的一部分。对target目标对象的方法调用会首先被AopProxy代理对象

拦截,对不同的AopProxy代理对象生成方式,会使用不同的拦截回调入口。


 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值