Spring AOP实现源码分析(三)


Spring AOP的实现可以分为三大部分
1. 注册AOP功能具体实现类

2. 普通Bean实例化时AOP的切入

3. AOP切入具体流程

下面分析BeanPostProcessor执行过程中,aop如何切入,上一节讲到,普通bean初始化会调用如下方法

// 调用AOP的真正实现方法入口  
    result = beanProcessor.postProcessAfterInitialization(result, beanName); 
 aop此方法实际是继承自AbstractAutoProxyCreator, 跟踪一下  postProcessAfterInitialization的实现


创建代理实际只有两个步骤

1. 获取增强方法或者增强器

2. 根据获取到的增强器进行代理

	
// class 
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  if (bean != null) {
    Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (!this.earlyProxyReferences.contains(cacheKey)) {
        // 进行aop包装
        return wrapIfNecessary(bean, beanName, cacheKey);
      }
  }
  return bean;
}

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  // 1. 获取增强器, 下面会详细拆分
  Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  // 如果获取到aop拦截器
  if (specificInterceptors != DO_NOT_PROXY) {
    this.advisedBeans.put(cacheKey, Boolean.TRUE);
    // 2. 创建代理
    Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    this.proxyTypes.put(cacheKey, proxy.getClass());
    // 最终返回aop代理类
    return proxy;
  }

首先跟踪 获取增强器 的逻辑

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
  // 封装在函数内
  List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
  if (advisors.isEmpty()) {
    return DO_NOT_PROXY;
  }
  return advisors.toArray();
}

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
  // 获取增强器,其内部实现具体为以下步骤
  // 1. 获取beanFactory所有的beanName
  // 2. 遍历所有beanName,找到声明为AspectJ的类
  // 3. 对第二步的类,进行增强器提取
  // 4. 将提取结果加入缓存(提升下次调用的的效率,因为每个bean都会走这个流程)
  // 增强器实际会根据method上的注解(Before, After...)初始化不同的类,比如 Before 注解对应 AspectJMethodBeforeAdvice
  List<Advisor> candidateAdvisors = findCandidateAdvisors();
  // 判断当前bean可用的增强器,因为不一定所有的增强器对当前bean适用
  List<Advisor> eligibleAdvisors = 
  findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
  extendAdvisors(eligibleAdvisors);
  if (!eligibleAdvisors.isEmpty()) {
    eligibleAdvisors = sortAdvisors(eligibleAdvisors);
  }
  return eligibleAdvisors;
}
  继续跟踪 创建代理 实现  
protected Object createProxy(
			Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
......
  // 统一处理封装所有的的增强器
  Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
......
  // 生成代理,并返回,生成代理会有两种方式
  // 对于实现了接口的类,默认使用jdk动态代理; 对于没有实现接口的类,只能使用cglib
  // 对于实现了接口的类,可以强制使用cglib(通过配置proxy-target-class="true")
  return proxyFactory.getProxy(getProxyClassLoader());
}
 代理的真正实现调用过程(jdk动态代理,或者cglib)不再赘述,比如动态代理,最终会调用invoke,稍微看一下JdkDynamicAopProxy的invoke实现,内部通过chain保存了增强器调用链,实现过程类似于职责链设计模式
// class JdkDynamicAopProxy
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
......
   // 获取并封装调用链chain,实际会对advisor进行转换,比如 (@Before注解)AspectJMethodBeforeAdvice
 会转换为 MethodBeforeAdviceInterceptor
  List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
  if (chain.isEmpty()) {	
    Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
    retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
  } else {
    // 代理方法执行
    invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
    // 实际执行比较有意思,会loop chain,但是需要仔细看逻辑才明白
    retVal = invocation.proceed();
  }
......
}

public Object proceed() throws Throwable {
  // interceptorsAndDynamicMethodMatchers实际是上面的调用链chain,若到达队尾,则跳出
  if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
    return invokeJoinpoint();
  }
  // 获取下一个interceptor
  Object interceptorOrInterceptionAdvice =			this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
......
  // 这个方法,将this传了进去,里面的实现可以看出,实际在执行完当前interceptor的invoke方法后,接着执行this.proceed,即又调用回来了当前proceed方法,保证loop chain完成
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}

// 比如 MethodBeforeAdviceInterceptor 的实现
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
  // advice封装了advisor
  this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
  // mi即为上面的invoke方法传入的this
  return mi.proceed();
}
 

猜你喜欢

转载自ballenlee.iteye.com/blog/2388240