天天看点

AOP注解执行流程

1、注解工作原理

@EnableAspectJAutoProxy

启动支持处理标有AspectJ的@Aspect批注的组件,类似于Spring的<aop:aspectj-autoproxy> XML元素中的功能。要在@Configuration类上使用。

注册BeanName的 internalAutoProxyCreator(AnnotationAwareAspectJAutoProxyCreator.class)的 BeanDefinetion,在实例化之前执行返回代理对象。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

/**
* 指示与基于标准Java接口的代理相反,是否要创建基于子类(CGLIB)的代理。默认为false。
*/
boolean proxyTargetClass() default false;

/**
* 指示代理应由AOP框架作为ThreadLocal公开,以便通过org.springframework.aop.framework.AopContext类进行检索。默认情况下为关闭,即不保证AopContext访问将正常进行。
*/
boolean exposeProxy() default false;

}

// AspectJAutoProxyRegistrar 
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
    }
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
    }
  }

}

// org.springframework.aop.config.AopConfigUtils

registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);

private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
      }
    }
return null;
  }
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
      
注册 AnnotationAwareAspectJAutoProxyCreator
@EnableAspectJAutoProxy
    --> @Import(AspectJAutoProxyRegistrar.class) 
    --> AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar
        --> AspectJAutoProxyRegistrar.registerBeanDefinitions
        -- AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
            -- registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
      
AnnotationAwareAspectJAutoProxyCreator 实现 InstantiationAwareBeanPostProcessor,Instantiation实例化之前执行。
graph TB
AnnotationAwareAspectJAutoProxyCreator-->AspectJAwareAdvisorAutoProxyCreator
AspectJAwareAdvisorAutoProxyCreator-->AbstractAdvisorAutoProxyCreator
AbstractAdvisorAutoProxyCreator-->AbstractAutoProxyCreator

AbstractAutoProxyCreator-.-SmartInstantiationAwareBeanPostProcessor
AbstractAutoProxyCreator-.-BeanFactoryAware
AbstractAutoProxyCreator-->ProxyProcessorSupport

SmartInstantiationAwareBeanPostProcessor-.-InstantiationAwareBeanPostProcessor
InstantiationAwareBeanPostProcessor-.-BeanPostProcessor
      

3、工作流程

3.1 创建和注册AnnotationAwareAspectJAutoProxyCreator的过程

  1. 创建ioc容器;
  2. 注册配置类,调用refresh()刷新容器;
  1. registerBeanPostProcessors(beanFactory); 注册bean的后置处理器来方便拦截bean的创建;
  1. 获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor;
  2. 注册BeanPostProcessorChecker,该日志将在以下情况下记录信息消息在BeanPostProcessor实例化期间(即当一个bean不适合所有BeanPostProcessor处理。
  3. 将BeanPostProcessor按照 PriorityOrdered、Ordered、nonOrdered、MergedBeanDefinitionPostProcessor保存到priorityOrderedPostProcessors、internalPostProcessors、orderedPostProcessorNames、nonOrderedPostProcessorNames 依次注册;
  4. 注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中;

    创建 internalAutoProxyCreator 的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】

  1. 创建Bean的实例;
  2. populateBean;给bean的各种属性赋值;
  3. initializeBean:初始化bean;
  1. invokeAwareMethods():处理Aware接口的方法回调;
  2. applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization();
  3. invokeInitMethods();执行自定义的初始化方法;
  4. applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization();
  1. BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功;--> initBeanFactory():aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
  2. 最后重新注册用于将内部bean检测为ApplicationListener的后处理器,将其移到处理器链的末尾(用于拾取代理等)。
  3. 把BeanPostProcessor注册到BeanFactory中;

    beanFactory.addBeanPostProcessor(postProcessor);

  1. finishBeanFactoryInitialization(beanFactory);完成BeanFactory初始化工作;创建剩下的非抽象非懒加载单实例bean;
  1. 遍历获取容器中所有的Bean,依次创建对象getBean(beanName);

    preInstantiateSingletons:getBean --> doGetBean --> getSingleton --> singletonFactory.getObject(); --> createBean --> doCreateBean

  2. createBean
  1. resolveBeforeInstantiation(beanName, mbdToUse); 生成代理对象,为null就继续执行 doCreateBean创建对象;
  2. doCreateBean AnnotationAwareAspectJAutoProxyCreator注册流程一致。
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
// 省略部分代码 .... 
// 给BeanPostProcessors一个返回代理而不是目标bean实例的机会
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
          }
// 实际创建指定的bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
          }


// AnnotationAwareAspectJAutoProxyCreator在所有bean创建之前会有一个拦截,InstantiationAwareBeanPostProcessor 实现会调用 
// postProcessBeforeInstantiation()  postProcessAfterInitialization()
// 【createBean:resolveBeforeInstantiation() 实现接口 InstantiationAwareBeanPostProcessor调用,bean实例化(doCreateBean)之前执行】
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                  }
                }
              }
mbd.beforeInstantiationResolved = (bean != null);
            }
return bean;
          }

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
                }
              }
            }
return null;
          }
      

3.2 AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】作用;

  1. bean实例化之前,调用AnnotationAwareAspectJAutoProxyCreator.postProcessBeforeInstantiation();
// 判断当前bean是否在advisedBeans中。
// isInfrastructureClass 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean、或者是否是切面(@Aspect);则   this.advisedBeans.put(cacheKey, Boolean.FALSE);返回NULL;

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);

if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
            }
// 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean、或者是否是切面(@Aspect),是则返回 NULL
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
            }
        }


// 如果我们有自定义的TargetSource,请在此处创建代理。
// 禁止目标Bean的不必要的默认实例化:
// TargetSource将以自定义方式处理目标实例。
if (beanName != null) {
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
            }
        }

return null;
    }
      
  1. bean初始化之后,调用 AnnotationAwareAspectJAutoProxyCreator.postProcessAfterInitialization,目标类返回代理对象;
  1. getAdvicesAndAdvisorsForBean --> findEligibleAdvisors --> findAdvisorsThatCanApply 查询符合目标类的AOP拦截器,并对增强器排序;
  2. specificInterceptors != DO_NOT_PROXY,创建代理对象;
  1. 将对应拦截器包装成 Advisor,保存进 proxyFactory;
  2. 给容器中返回当前组件使用cglib增强了的代理对象;
  3. 以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;
// 如果Bean被子类标识为要代理的bean,则使用配置的拦截器创建代理 AnnotationAwareAspectJAutoProxyCreator.postProcessAfterInitialization
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
return bean;
    }

// 包装Bean的代理,或按原样包装Raw Bean实例
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
        }
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
        }
// 判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean、或者是否是切面(@Aspect),是则返回 NULL
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
        }

// 获取当前bean的所有增强器(通知方法)  Object[]  specificInterceptors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, 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;
        }

this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
    }


// getAdvicesAndAdvisorsForBean --> findEligibleAdvisors --> findAdvisorsThatCanApply  查询符合目标类的AOP拦截器
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
return eligibleAdvisors;
    }


// eligibleAdvisors 可用增强器集合,
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
        }
List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
            }
        }
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
            }
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
            }
        }
return eligibleAdvisors;
    }

// 创建AOP代理对象
protected Object createProxy(Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }

ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);

if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
            }
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
// 将对应拦截器包装成Advisor,保存进proxyFactory;
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
for (Advisor advisor : advisors) {
proxyFactory.addAdvisor(advisor);
        }

proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);

proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
        }

return proxyFactory.getProxy(getProxyClassLoader());
    }   

// DefaultAopProxyFactory.createAopProxy() 使用cglib或者是jdk代理
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
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.");
            }
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
            }
return new ObjenesisCglibAopProxy(config);
        }
else {
return new JdkDynamicAopProxy(config);
        }
    }

      

2.3 AOP代理类目标方法执行;

AOP 代理对象信息(比如增强器,目标对象,xxx;
AOP注解执行流程
  1. org.springframework.aop.framework.CglibAopProxy.intercept();拦截目标方法的执行;
  2. 根据ProxyFactory对象获取将要执行的目标方法拦截器链;

    List

  3. 如果没有拦截器链,直接执行目标方法;

    拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)

  4. 如果有拦截器链,把需要执行的目标对象,目标方法,

    拦截器链等信息传入创建一个 CglibMethodInvocation 对象,

    并调用 Object retVal = mi.proceed();

  5. 拦截器链的触发过程;
  1. 如果没有拦截器执行执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法;
  2. 链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行;

    拦截器链的机制,保证通知方法与目标方法的执行顺序;

AOP注解执行流程

3 总结

  1. @EnableAspectJAutoProxy 开启AOP功能
  2. @EnableAspectJAutoProxy 会给容器中注册一个组件 AnnotationAwareAspectJAutoProxyCreator
  3. AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
  4. 容器的创建流程:

    4.1. registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象

    4.2. finishBeanFactoryInitialization()初始化剩下的单实例bean

         4.2.1. 创建业务逻辑组件和切面组件

         4.2.2. AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程

         4.2.3. 组件创建完之后,判断组件是否需要增强

              是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);

  5. 执行目标方法:

    5.1 代理对象执行目标方法

    5.2 CglibAopProxy.intercept();

         5.2.1 得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)

         5.2.2 利用拦截器的链式机制,依次进入每一个拦截器进行执行;

         5.2.3 效果:

              正常执行:前置通知-》目标方法-》后置通知-》返回通知

              出现异常:前置通知-》目标方法-》后置通知-》异常通知