(Spring源碼分析)Spring Aop動態代理織入源碼


Spring Aop的核心就是生成動態代理動態代理織入,本篇主要講Spring Aop動態代理織入Spring Aop生成動態代理Spring Aop生成動態代理博文中

織入的定義

將目標對象中和其他對象連接起來的過程叫做織入

織入的種類

  • 編譯期織入

執行效率高,不夠靈活

  • 裝載時注入

稍微靈活,可以在JVM裝載目標類對象和聲明類對象的時候進行合併,執行效率不夠高

  • 運行時織入(動態代理織入)

最靈活,通過配置文件進行目標類對象和通知進行合併的,效率低

Spring Aop屬於運行時織入AspectJ採用編譯期織入和類裝載期織入

Spring Aop在調用調用代理方法時,使用責任鏈設計模式來對目標對象和通知對象執行合併,從而達到在程序運行時織入

調用代理方法

invoke(proxy, method, args)

/**
 * 也就是當Proxy對象的代理方法被調用時,JdkDynamicAopProxy的的invoke方法作爲Proxy對象的回調函數被觸發,從而通過invoke的具體實現,來完成對目標對象方法調用的攔截或者說功能的增強工作
 * 在Proxy.newProxyInstance(classLoader, proxiedInterfaces, this)生成動態代理對象時,this需要時實現了InvocationHandler接口,並重寫invoke()方法,在invoke()方法中定義代理對象的邏輯
 */
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  Object oldProxy = null;
  boolean setProxyContext = false;

  TargetSource targetSource = this.advised.targetSource;
  Object target = null;

  try {
    if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
      return equals(args[0]);
    }
    else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
      return hashCode();
    }
    else if (method.getDeclaringClass() == DecoratingProxy.class) {
      return AopProxyUtils.ultimateTargetClass(this.advised);
    }
    else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
             method.getDeclaringClass().isAssignableFrom(Advised.class)) {
      return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
    }

    Object retVal;

    if (this.advised.exposeProxy) {
      oldProxy = AopContext.setCurrentProxy(proxy);
      setProxyContext = true;
    }

    target = targetSource.getTarget();
    Class<?> targetClass = (target != null ? target.getClass() : null);

    // 根據切面方法獲取攔截器鏈
    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

    // 如果攔截器鏈不存在,就直接調用目標對象的方法
    if (chain.isEmpty()) {
      Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
      retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
    }

    // 如果攔截器鏈存在,就對目標對象的方法進行增強
    // 需要在調用目標對象的方法前後調用攔截器方法
    else {
      // 根據proxy(代理對象)、target(目標對象)、method(方法對象)、args(目標對象調用的方法參數)、targetClass(目標對象的Class對象)、chain(攔截器鏈)來生成攔截器鏈
      MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);

      // 通過責任鏈模式來連接攔截器鏈
      retVal = invocation.proceed();
    }

    Class<?> returnType = method.getReturnType();
    if (retVal != null && retVal == target &&
        returnType != Object.class && returnType.isInstance(proxy) &&
        !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
      retVal = proxy;
    }
    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) {
      AopContext.setCurrentProxy(oldProxy);
    }
  }
}

invocation.proceed()

public Object proceed() throws Throwable {
  // //從-1開始計數
  if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
    // 調用目標對象方法
    return invokeJoinpoint();
  }

  // 從攔截器鏈中獲取MethodInterceptor攔截器,然後currentInterceptorIndex並進行++currentInterceptorIndex
  Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);

  // 如果MethodInterceptor攔截器是InterceptorAndDynamicMethodMatcher類型的
  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 {
    // 這裏this爲當前ReflectiveMethodInvocation對象
    // 在invoke()方法中也進行遞歸調用
    return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
  }
}
invokeJoinpoint()
/**
 * 調用目標對象方法
 */
protected Object invokeJoinpoint() throws Throwable {
  return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}

/**
 * 調用目標對象方法的真正實現
 */
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
  throws Throwable {

  // 利用反射來執行目標對象的方法
  try {
    ReflectionUtils.makeAccessible(method);
    return method.invoke(target, args);
  }
  catch (InvocationTargetException ex) {
    throw ex.getTargetException();
  }
  catch (IllegalArgumentException ex) {
    throw new AopInvocationException("AOP configuration seems to be invalid: tried calling method [" + method + "] on target [" + target + "]", ex);
  }
  catch (IllegalAccessException ex) {
    throw new AopInvocationException("Could not access method [" + method + "]", ex);
  }
}

用來處理@Before@After@AfterRunning@AfterThrowing方法的類都實現了MethodInterceptor接口,重寫了invoke()方法,在方法中各自實現了不同的邏輯

@Before的處理類MethodBeforeAdviceInterceptor
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {

  private final MethodBeforeAdvice advice;

  @Override
  public Object invoke(MethodInvocation mi) throws Throwable {
		// 執行前置通知方法
    this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());

		// 回調方法,在這裏進行調用後面的MethodInvocation攔截器
    return mi.proceed();
  }
}
@After的處理類AspectJAfterAdvice
public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice, Serializable {

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			// 執行後置通知方法
			return mi.proceed();
		}
		finally {
			invokeAdviceMethod(getJoinPointMatch(), null, null);
		}
	}
}
@AfterRunning的處理類AfterReturningAdviceInterceptor
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {

	private final AfterReturningAdvice advice;

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		Object retVal = mi.proceed();
		
		// 執行最終通知方法
		this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
		return retVal;
	}
}
@AfterThrowing的處理類AspectJAfterThrowingAdvice
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice, Serializable {

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		try {
			// 執行異常通知方法
			return mi.proceed();
		}
		catch (Throwable ex) {
			if (shouldInvokeOnThrowing(ex)) {
				invokeAdviceMethod(getJoinPointMatch(), null, ex);
			}
			throw ex;
		}
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章