(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;
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值