Spring AOP源碼解析(三)創建代理並調用

一、創建代理準備工作

回顧之前的wrapIfNecessary方法,再獲取到匹配的增強器後,Spring就會爲攔截的bean創建代理對象:

		//獲取匹配的增強器
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		//DO_NOT_PROXY = null
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			//創建代理
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

創建代理createProxy:

	protected Object createProxy(
			Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
		//在bean對應的BeanDefinition中添加原Class對象屬性(保存bean原本的Class)
		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
		}

		ProxyFactory proxyFactory = new ProxyFactory();
		//獲取當前類中配置的屬性
		proxyFactory.copyFrom(this);
		
		//檢查proxyTargetClass屬性
		if (!proxyFactory.isProxyTargetClass()) {
			//檢查beanDefinitioin中是否包含preserveTargetClass屬性,且屬性爲true
			//設置是否使用CGLib進行代理
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				//篩選代理接口並添加到proxyFactory
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
		
		//獲取增強器(包括前面篩選出來的增強器,以及通過setInterceptorNames中添加的通用增強器,默認爲空)
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		for (Advisor advisor : advisors) {
			//將所有增強器添加到proxyFactory
			proxyFactory.addAdvisor(advisor);
		}
		
		//設置需要代理的bean對象信息
		proxyFactory.setTargetSource(targetSource);
		//模版方法,由子類定製化代理
		customizeProxyFactory(proxyFactory);
		//用來控制代理工程被配置後,是否還允許修改代理的配置,默認爲false
		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}

		//創建代理對象
		return proxyFactory.getProxy(getProxyClassLoader());
	}

上面代理流程爲:

  1. 在BeanDefinition中保存bean原Class對象,因爲創建代理後,bean的class會被修改(Spring4中新加入的帶你,Spring3中不包含)
  2. 創建ProxyFactory
  3. 設置屬性
  4. 過濾目標bean的接口,並添加到ProxyFactory
  5. 獲取增強器實例,添加到ProxyFactory中
  6. 創建代理

過濾接口

過濾接口中主要功能是,幫助判斷是否使用JDK的動態代理來創建代理。因爲JDK動態代理的條件是bean實現了接口,所以Spring會將目標bean實現的接口過濾後添加到ProxyFactory中,方便判斷是否使用JDK動態代理,下面是evaluateProxyInterfaces實現:

	protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
		//獲取所有實現的接口
		Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
		boolean hasReasonableProxyInterface = false;
		for (Class<?> ifc : targetInterfaces) {
			//不是Spring內部回調用的接口 && 不是語言內部接口 && 接口定義了一個以上的方法
			if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
					ifc.getMethods().length > 0) {
				hasReasonableProxyInterface = true;
				break;
			}
		}
		//如果滿足上面三個條件,纔會將接口添加到proxyFactory
		if (hasReasonableProxyInterface) {
			// Must allow for introductions; can't just set interfaces to the target's interfaces only.
			for (Class<?> ifc : targetInterfaces) {
				proxyFactory.addInterface(ifc);
			}
		}
		//條件不滿足,缺少合適的接口,無法使用JDK動態代理,使用CGLib
		else {
			proxyFactory.setProxyTargetClass(true);
		}
	}

下面是過濾條件:

1.Spring內部接口

會排除掉InitializingBean、DisposableBean、Aware接口

	protected boolean isConfigurationCallbackInterface(Class<?> ifc) {
		return (InitializingBean.class == ifc || DisposableBean.class == ifc ||
				ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));
	}

2、是否是語言內部接口 isInternalLanguageInterface

	protected boolean isInternalLanguageInterface(Class<?> ifc) {
		return (ifc.getName().equals("groovy.lang.GroovyObject") ||
				ifc.getName().endsWith(".cglib.proxy.Factory"));
	}

其實就是比較類名

3、接口中是否定義了方法

二、創建代理

ProxyFactory.getProxy:

	public Object getProxy(ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

createAopProxy:

	protected final synchronized AopProxy createAopProxy() {
		//active會在在第一次創建代理後,設爲true
		if (!this.active) {
			//設置active爲true,並通知監聽器(如果沒有配置,爲空)
			activate();
		}
		//getAopProxyFactory會返回aopProxyFactory變量,默認實現爲DefaultAopProxyFactory
		return getAopProxyFactory().createAopProxy(this);
	}

代碼流程:

  1. 如果是第一次創建代理,會通知ProxyFactory中註冊的監聽器
  2. 獲取類中定義的aopProxyFactory變量,默認實現爲DefaultAopProxyFactory
  3. 通過DefaultAopProxyFactory創建代理對象(會傳入當前對象,用於獲取配置信息)

DefaultAopProxyFactory-->createAopProxy:

	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			//代理目標bean的Class不能爲空
			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.");
			}
			//如果是接口 或者 Class類型爲Proxy
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

Spring生成代理對象的方式有兩種,JDK動態代理和CGLib,分別生成JdkDynamicAopProxy和ObjenesisCglibAopProxy,從上面代碼可以看出Spring的判斷條件

  1. optimize:用來控制通過CGLib創建的代理是否使用激進的優化策略(該僅對CGLib有效)
  2. proxyTargetClass:當屬性爲true,使用CGLib,設置方式:<aop:aspectj-autoproxy proxy-target-class="true">。
  3. 是否存在代理接口(也就是前面過濾接口一節中,添加進去的接口)
  4. 如果目標類是接口的話,還是會使用JDK的方式進行代理

JDK動態代理與CGLib的區別:

  • JDK只能針對實現了接口的類生成代理
  • CGLib是針對類實現代理,主要通過生成目標類的子類,覆蓋其中的方法來達到代理的目的。因此,目標類或方法不能被定義爲final

三、獲取代理對象

回顧之前getProxy創建代理的代碼:

	public Object getProxy(ClassLoader classLoader) {
		return createAopProxy().getProxy(classLoader);
	}

getAopProxy就是上一節中獲取到的AopProxy實例:JdkDynamicAopProxy或ObjenesisCglibAopProxy,後面會調用其getProxy獲取代理對象:

	public Object getProxy(ClassLoader classLoader) {
		//log...
		//獲取代理接口
		Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
		//檢查是否在接口中定義了equals或hashCode方法
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		//創建代理對象
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}

上面代碼流程:

  1. 獲取代理接口
  2. 檢查是否在接口中定義了equals或hashCode方法
  3. 使用JDK動態代理Proxy.newProxyInstance創建代理對象

四、方法攔截過程

JDK生成代理對象需要調用return Proxy.newProxyInstance,並傳入類加載器、代理接口、以及一個InvocationHandler實例。其中InvocationHandler的invoke方法定義了代理的流程。

上面代碼中,傳入的InvocationHandler是this,即JdkDynamicAopProxy,該類實現了InvocationHandler接口,下面是其invoke方法實現:

	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		MethodInvocation invocation;
		Object oldProxy = null;
		boolean setProxyContext = false;

		//獲取原對象信息
		TargetSource targetSource = this.advised.targetSource;
		Class<?> targetClass = null;
		Object target = null;

		try {
			//如果接口中定義了equals或hashCode方法,則進行專門處理
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				// The target does not implement the equals(Object) method itself.
				return equals(args[0]);
			}
			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				// The target does not implement the hashCode() method itself.
				return hashCode();
			}
			else if (method.getDeclaringClass() == DecoratingProxy.class) {
				// There is only getDecoratedClass() declared -> dispatch to proxy config.
				return AopProxyUtils.ultimateTargetClass(this.advised);
			}
			//opaque屬性,表示是否禁止將代理對象轉換爲Advised對象,默認是false
			//如果調用的方法來自Advised接口
			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				//通過反射Method.invoke,調用advised(傳入的ProxyFactory實例,該類實現了Advised接口)對應的方法
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal;
			//爲了解決目標對象內部的自我調用無法實施切面中的增強,需要暴露代理對象
			if (this.advised.exposeProxy) {
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			// 獲取目標對象信息
			target = targetSource.getTarget();
			if (target != null) {
				targetClass = target.getClass();
			}

			// 獲取當前方法的攔截器鏈
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			// 如果沒有任何攔截器,則調用直接對原目標對象調用方法
			if (chain.isEmpty()) {
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
				// 將攔截器鏈封裝到ReflectiveMethodInvocation,方便使用其proceed進行鏈式調用攔截器
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// 執行攔截器鏈
				retVal = invocation.proceed();
			}

			// Massage return value if necessary.
			Class<?> returnType = method.getReturnType();
			if (retVal != null && retVal == target &&
					returnType != Object.class && returnType.isInstance(proxy) &&
					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
				// 特殊情況:爲了防止方法返回"return this",返回原目標對象,會將返回值替換爲代理對象
				retVal = proxy;
			}
			//如果返回類型是基本類型兵器,但是返回結果爲null,拋出異常
			else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
				throw new AopInvocationException(
						"Null return value from advice does not match primitive return type for: " + method);
			}
			return retVal;
		}
		finally {
			if (target != null && !targetSource.isStatic()) {
				// Must have come from TargetSource.
				targetSource.releaseTarget(target);
			}
			if (setProxyContext) {
				// Restore old proxy.
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}

代碼流程:

  1. 特殊方法的處理,包括equalshashCode方法以及定義在Advised接口中的方法
  2. 獲取方法匹配的增強器,並生成攔截器鏈並調用
  3. 對方法返回結果進行處理:如果返回“this”,即原目標對象,則會替換爲返回代理對象;如果返回結果爲null,但返回類型爲基本數據類型(int、char等)則拋出異常

1、獲取匹配的攔截器:

	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
		//緩存的cacheKey,先嚐試從緩存獲取,不存在再從ProxyFactory中解析
		MethodCacheKey cacheKey = new MethodCacheKey(method);
		List<Object> cached = this.methodCache.get(cacheKey);
		if (cached == null) {
			//通過實例方法和ProxyFactory中保存的信息,解析出匹配的增強
			cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
					this, method, targetClass);
			this.methodCache.put(cacheKey, cached);
		}
		return cached;
	}

方法匹配增強器的功能交由advisorChainFactory(DefaultAdvisorChainFactory)完成:

	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, Class<?> targetClass) {

		List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
		Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
		//方法是否匹配引介增強
		boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
		AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
		
		//遍歷增強器
		for (Advisor advisor : config.getAdvisors()) {
			//PointcutAdvisor類型的增強器
			//通過@Aspect加入的增強器類型爲InstantiationModelAwarePointcutAdvisorImpl,實現了PointcutAdvisor
			if (advisor instanceof PointcutAdvisor) {
				// Add it conditionally.
				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
				if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
					MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
					if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
						if (mm.isRuntime()) {
							// Creating a new object instance in the getInterceptors() method
							// isn't a problem as we normally cache created chains.
							for (MethodInterceptor interceptor : interceptors) {
								interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
							}
						}
						else {
							interceptorList.addAll(Arrays.asList(interceptors));
						}
					}
				}
			}
			//對於引介增強的處理
			else if (advisor instanceof IntroductionAdvisor) {
				IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
				if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
					Interceptor[] interceptors = registry.getInterceptors(advisor);
					interceptorList.addAll(Arrays.asList(interceptors));
				}
			}
			else {
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			}
		}

		return interceptorList;
	}

上面代碼首先會遍歷攔截增強器,然後根據目標類和目標方法(引介增強外)匹配增強器,如果匹配的話,返回增強器包裝的攔截器(Advice)

對於@Aspect註解配置類中,@Before、@After、@AfterThrowing配置的增強會被包裝爲AspectJMethodBeforeAdvice、AspectJAfterReturningAdvice、AspectJAfterThrowingAdvice等,在這一步驟中,這些Advice會分別被封裝爲MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor攔截器。

 

2、創建攔截器鏈並調用

Spring會在獲取到方法匹配的攔截器後,將代理對象、目標對象、調用方法、參數、攔截器等信息封裝到ReflectiveMethodInvocation中:

	protected ReflectiveMethodInvocation(
			Object proxy, Object target, Method method, Object[] arguments,
			Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {

		this.proxy = proxy;
		this.target = target;
		this.targetClass = targetClass;
		this.method = BridgeMethodResolver.findBridgedMethod(method);
		this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
		this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
	}

然後調用ReflectiveMethodInvocation的proceed方法:

	public Object proceed() throws Throwable {
		//	執行完所有增強後,執行切點方法
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}
		
		//獲取下一個攔截器
		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			//動態匹配
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else {
				//不匹配則不執行攔截器
				return proceed();
			}
		}
		else {
			// 普通攔截器。比如:MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor、ThrowsAdviceInterceptor
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

通過currentInterceptorIndex記錄當前攔截器的索引,每調用一個攔截器就+1,再次調用proceed方法時就會獲取下一個攔截器調用。

3、攔截器調用

在獲取增強器的過程中,例如@Before註解標註的方法會被封裝爲AspectJMethodBeforeAdvice,然後會在 1.獲取匹配的攔截器 過程中,會被包裝爲MethodInterceptor(MethodBeforeAdviceInterceptor),下面是Advice轉換爲MethodInterceptor的過程:

DefaultAdvisorAdapterRegistry.getInterceptors:

	public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
		List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
		//獲取Advice
		Advice advice = advisor.getAdvice();
		//如果Advice實例同時已經實現MethodInterceptor接口,則直接使用
		if (advice instanceof MethodInterceptor) {
			interceptors.add((MethodInterceptor) advice);
		}
		//需要使用適配器來轉換Advice接口
		for (AdvisorAdapter adapter : this.adapters) {
			if (adapter.supportsAdvice(advice)) {
				interceptors.add(adapter.getInterceptor(advisor));
			}
		}
		if (interceptors.isEmpty()) {
			throw new UnknownAdviceTypeException(advisor.getAdvice());
		}
		return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
	}

代碼流程:

  1. 如果Advice增強已經實現了MethodInterceptor,則不需要轉換,可以直接使用。例如:@After註解標註的增強方法會被表示爲AspectJAfterAdvice,該類同時實現了Advice和MethodInterceptor接口,也就是已經在類中規定好了攔截的邏輯。
  2. Advice實現了沒有同時實現MethodInterceptor,所以需要使用內置的適配器將Advice增強轉換爲MethodInterceptor攔截器。

a、內置的Advice適配器

在前面的代碼中,將Advice轉換爲MethodInterceptor的工作是交給this.adapters來完成的,該變量定義如下;

private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);

並且在DefaultAdvisorAdapterRegistry的構造函數中,對該變量進行了初始化填充:

	public DefaultAdvisorAdapterRegistry() {
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
	}

可以看到,Spring實現會加入3個默認的是Advice適配器:MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter。

這三個適配器通過support方法,驗證是否是否支持傳入的Advice對象,如果支持,會將Advice實例封裝爲對應的MethodInterceptor實例:

MethodBeforeAdviceAdapter:

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof MethodBeforeAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
		return new MethodBeforeAdviceInterceptor(advice);
	}

}

AfterReturningAdviceAdapter:

class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof AfterReturningAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
		return new AfterReturningAdviceInterceptor(advice);
	}

}

ThrowsAdviceAdapter:

class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable {

	@Override
	public boolean supportsAdvice(Advice advice) {
		return (advice instanceof ThrowsAdvice);
	}

	@Override
	public MethodInterceptor getInterceptor(Advisor advisor) {
		return new ThrowsAdviceInterceptor(advisor.getAdvice());
	}

}

下面是對三種適配器的總結:

適配器 支持的Advice接口 Advice實現類 對應註解
MethodBeforeAdviceAdapter MethodBeforeAdvice AspectJMethodBeforeAdvice @Before
AfterReturningAdviceAdapter AfterReturningAdvice AspectJAfterReturningAdvice @AfterReturning
ThrowsAdviceAdapter ThrowsAdvice

 

 

 

 

 

下面再來總結一下通過註解配置的增強對應的攔截器:

註解 Advice MethodInterceptor
@Before AspectJMethodBeforeAdvice MethodBeforeAdviceInterceptor
@After AspectJAfterAdvice AspectJAfterAdvice
@AfterReturning AspectJAfterReturningAdvice AfterReturningAdviceInterceptor
@AfterThrowing AspectJAfterThrowingAdvice AspectJAfterThrowingAdvice
@Around  AspectJAroundAdvice AspectJAroundAdvice

 

 

 

 

 

 

 

b、攔截器調用

攔截器的類型有多中,下面我們分析由@Before註解添加的攔截器MethodBeforeAdviceInterceptor。

MethodBeforeAdviceInterceptor定義:

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {

	private MethodBeforeAdvice advice;

	/**
	 * 將傳入的MethodBeforeAdvice封裝爲MethodBeforeAdviceInterceptor
	 * @param advice the MethodBeforeAdvice to wrap
	 */
	public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
		Assert.notNull(advice, "Advice must not be null");
		this.advice = advice;
	}

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
		return mi.proceed();
	}
}

從invoke方法中可以看到,攔截器會在調用真正方法前,調用MethodBeforeAdvice的before方法,在這一步,也就完成了方法的前置增強。

下面看一下AspectJMethodBeforeAdvice的before實現:

	public void before(Method method, Object[] args, Object target) throws Throwable {
		invokeAdviceMethod(getJoinPointMatch(), null, null);
	}
	
	protected Object invokeAdviceMethod(JoinPointMatch jpMatch, Object returnValue, Throwable ex) throws Throwable {
		//將參數綁定後,傳入invokeAdviceMethodWithGivenArgs方法執行
		return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
	}

invokeAdviceMethodWithGivenArgs:

	protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
		Object[] actualArgs = args;
		//如果advice增強方法參數爲空
		if (this.aspectJAdviceMethod.getParameterTypes().length == 0) {
			actualArgs = null;
		}
		try {
			ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);
			// 通過反射,調用增強方法
			return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);
		}
		catch (IllegalArgumentException ex) {
			throw new AopInvocationException("Mismatch on arguments to advice method [" +
					this.aspectJAdviceMethod + "]; pointcut expression [" +
					this.pointcut.getPointcutExpression() + "]", ex);
		}
		catch (InvocationTargetException ex) {
			throw ex.getTargetException();
		}
	}

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章