1. 程式人生 > >【Spring原始碼--AOP的實現】(一)AopProxy代理物件的建立

【Spring原始碼--AOP的實現】(一)AopProxy代理物件的建立

public Object getProxy(ClassLoader classLoader) {
		if (logger.isDebugEnabled()) {
			logger.debug("Creating CGLIB2 proxy: target source is "
					+ this.advised.getTargetSource());
		}
		try {
			// 從代理建立輔助類中獲取在IoC容器中配置的目標物件
			Class rootClass = this.advised.getTargetClass();
			Assert.state(rootClass != null,"Target class must be available for creating a CGLIB proxy");
			// 將目標物件本身做為自己的基類
			Class proxySuperClass = rootClass;
			// 檢查獲取到的目標類是否是CGLIB產生的
			if (AopUtils.isCglibProxyClass(rootClass)) {
				// 如果目標類是有CGLIB產生的,獲取目標類的基類
				proxySuperClass = rootClass.getSuperclass();
				// 獲取目標類的介面
				Class[] additionalInterfaces = rootClass.getInterfaces();
				// 將目標類的介面新增到容器AOP代理建立輔助類的配置中
				for (Class additionalInterface : additionalInterfaces) {
					this.advised.addInterface(additionalInterface);
				}
			}
			// 校驗代理基類
			validateClassIfNecessary(proxySuperClass);
			// 配置CGLIB的Enhancer類,Enhancer是CGLIB中的主要操作類
			Enhancer enhancer = createEnhancer();
			if (classLoader != null) {
				enhancer.setClassLoader(classLoader);
				if (classLoader instanceof SmartClassLoader&& ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
					enhancer.setUseCache(false);
				}
			}
			// 設定enhancer的基類
			enhancer.setSuperclass(proxySuperClass);
			enhancer.setStrategy(new UndeclaredThrowableStrategy(UndeclaredThrowableException.class));
			// 設定enhancer的介面
			enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
			enhancer.setInterceptDuringConstruction(false);
			// 設定enhancer的回撥方法
			Callback[] callbacks = getCallbacks(rootClass);
			enhancer.setCallbacks(callbacks);
			// 將通知器中配置作為enhancer的方法過濾
			enhancer.setCallbackFilter(new ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap,
					this.fixedInterceptorOffset));
			Class[] types = new Class[callbacks.length];
			for (int x = 0; x < types.length; x++) {
				types[x] = callbacks[x].getClass();
			}
			// 設定enhancer的回撥型別
			enhancer.setCallbackTypes(types);
			// 建立代理物件
			Object proxy;
			if (this.constructorArgs != null) {
				proxy = enhancer.create(this.constructorArgTypes,this.constructorArgs);
			} else {
				proxy = enhancer.create();
			}
			return proxy;
		} 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的代理物件。這個時候已經不會讓應用直接呼叫target的方法實現了,而是先被AopProxy代理物件攔截,對於不同的Aopproxy代理物件的不同生成方法,攔截入口不同。比如:JDK使用的是InvocationHandler使用的是invoke入口,二Cglib使用的是設定好的callback回撥。