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();
    5. BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功;--> initBeanFactory():aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
    6. 最后重新注册用于将内部bean检测为ApplicationListener的后处理器,将其移到处理器链的末尾(用于拾取代理等)。
    7. 把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;

image

  1. org.springframework.aop.framework.CglibAopProxy.intercept();拦截目标方法的执行;
  2. 根据ProxyFactory对象获取将要执行的目标方法拦截器链;
    List
posted @ 2021-07-28 16:48  光后的影子  阅读(469)  评论(0)    收藏  举报