[笔记迁移][Spring注解驱动]AOP相关[2]

版权声明:Collected by Bro_Rabbit only for study https://blog.csdn.net/weixin_38240095/article/details/86494804

三、AOP相关

1. 开启基于注解的AOP代理

给配置类标注@EnableAspectJAutoProxy(当然,切面对象与被增强对象添加到容器中),相当于之前配置文件的<aop:aspectj-autoproxy/>

2. @EnableAspectJAutoProxy原理

注:很多形式相似的注解@Enablexxx表示开启xxx功能,深入时应该找出为容器注册的组件、组件工作时机、组件功能

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
//将AspectJAutoProxyRegistrar组件[源码在下一段]导入至容器,自定义给IoC注册代理一个组件:internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator[AOP核心]

@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	/**
	 * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
	 * to standard Java interface-based proxies. The default is {@code false}.
	 */
	boolean proxyTargetClass() default false;

	/**
	 * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
	 * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
	 * Off by default, i.e. no guarantees that {@code AopContext} access will work.
	 * @since 4.3.1
	 */
	boolean exposeProxy() default false;

}
/**
 * Registers an {@link org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
 * AnnotationAwareAspectJAutoProxyCreator} against the current {@link BeanDefinitionRegistry}
 * as appropriate based on a given @{@link EnableAspectJAutoProxy} annotation.
 *
 * @author Chris Beams
 * @author Juergen Hoeller
 * @since 3.1
 * @see EnableAspectJAutoProxy
 */
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	/**
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
	 * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
	 * {@code @Configuration} class.
	 */
	@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);
		}
	}

}
/**
 * Utility class for handling registration of AOP auto-proxy creators.
 *
 * <p>Only a single auto-proxy creator can be registered yet multiple concrete
 * implementations are available. Therefore this class wraps a simple escalation
 * protocol, allowing classes to request a particular auto-proxy creator and know
 * that class, {@code or a subclass thereof}, will eventually be resident
 * in the application context.
 *
 * @author Rob Harrop
 * @author Juergen Hoeller
 * @author Mark Fisher
 * @since 2.5
 * @see AopNamespaceUtils
 */
public abstract class AopConfigUtils {

	/**
	 * The bean name of the internally managed auto-proxy creator.
	 */
	public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
			"org.springframework.aop.config.internalAutoProxyCreator";

	/**
	 * Stores the auto proxy creator classes in escalation order.
	 */
	private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<Class<?>>();

	/**
	 * Setup the escalation list.
	 */
	static {
		APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
	}

   	public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {

   		return registerAutoProxyCreatorIfNecessary(registry, null);

   	}

   	public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {

   		return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);

   	}

   	public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {

   		return registerAspectJAutoProxyCreatorIfNecessary(registry, null);

   	}

   	public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {

   		return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source);

   	}

   	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {

   		return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);

   	}

   	public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {

   		return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);

   	}

   	public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {

   		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {

   			BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);

   			definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);

   		}

   	}

   	public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {

   		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {

   			BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);

   			definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);

   		}

   	}

   	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;

   	}

   	private static int findPriorityForClass(Class<?> clazz) {

   		return APC_PRIORITY_LIST.indexOf(clazz);

   	}

   	private static int findPriorityForClass(String className) {

   		for (int i = 0; i < APC_PRIORITY_LIST.size(); i++) {

   			Class<?> clazz = APC_PRIORITY_LIST.get(i);

   			if (clazz.getName().equals(className)) {

   				return i;

   			}

   		}

   		throw new IllegalArgumentException(

   				"Class name [" + className + "] is not a known auto-proxy creator class");

   	}

   }

AnnotationAwareAspectJAutoProxyCreator原理分析

AutoProxyCreator
AbstractAutoProxyCreator implements SmartInstantionAwareBeanPostProcessor, BeanFactoryAware,根据继承树可知,AnnotationAwareAspectJAutoProxyCreator具备一个后置处理器及自动装配工厂的功能特点
(1)沿着继承树简单分析
   - AbstractAutoProxyCreator # setBeanFactory()
   - AbstractAutoProxyCreator#具备业务逻辑的后置处理器相关(postProcessBeforeInstantiation / postProcessAfterInitialization) [Breakpoint]
   - AbstractAdvisorAutoProxyCreator#setBeanFactory()重写父类逻辑[Breakpoint],调用自定义initBeanFactory(ConfigurableListableBeanFactory)
   - AnnotationAwareAspectJAutoProxyCreator#initBeanFactory()重写父类逻辑[Breakpoint]

(2)断点流程
    [1] 创建IoC容器,传入配置类
    [2] 注册配置类,刷新容器(核心方法refresh())
    [3] registerBeanPostProcessors(BeanFactory) 注册后置处理器拦截Bean的创建

   //org.springframework.context.support.PostProcessorRegistrationDelegate

   	public static void registerBeanPostProcessors(
   			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
   		//获取IoC容器中已经定义的所有BeanPostProcessor,还未创建其实例
   		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

   		// Register BeanPostProcessorChecker that logs an info message when
   		// a bean is created during BeanPostProcessor instantiation, i.e. when
   		// a bean is not eligible for getting processed by all BeanPostProcessors.
   		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

   		// Separate between BeanPostProcessors that implement PriorityOrdered,
   		// Ordered, and the rest.
   		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
   		List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
   		List<String> orderedPostProcessorNames = new ArrayList<String>();
   		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
   		for (String ppName : postProcessorNames) {
   			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
   				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
   				priorityOrderedPostProcessors.add(pp);
   				if (pp instanceof MergedBeanDefinitionPostProcessor) {
   					internalPostProcessors.add(pp);
   				}
   			}
   			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
   				orderedPostProcessorNames.add(ppName);
   			}
   			else {
   				nonOrderedPostProcessorNames.add(ppName);
   			}
   		}

   		// First, register the BeanPostProcessors that implement PriorityOrdered.
   		sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
   		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

   		// Next, register the BeanPostProcessors that implement Ordered.
   		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
   		for (String ppName : orderedPostProcessorNames) {
   			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
   			orderedPostProcessors.add(pp);
   			if (pp instanceof MergedBeanDefinitionPostProcessor) {
   				internalPostProcessors.add(pp);
   			}
   		}
   		sortPostProcessors(beanFactory, orderedPostProcessors);
   		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

   		// Now, register all regular BeanPostProcessors.
   		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
   		for (String ppName : nonOrderedPostProcessorNames) {
                //doGetBean()->getSingleton()->getObject()->createBean()
             	 //注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象并保存在容器中
   			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
   			nonOrderedPostProcessors.add(pp);
   			if (pp instanceof MergedBeanDefinitionPostProcessor) {
   				internalPostProcessors.add(pp);
   			}
   		}
   		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

   		// Finally, re-register all internal BeanPostProcessors.
   		sortPostProcessors(beanFactory, internalPostProcessors);
   		registerBeanPostProcessors(beanFactory, internalPostProcessors);

   		// Re-register post-processor for detecting inner beans as ApplicationListeners,
   		// moving it to the end of the processor chain (for picking up proxies etc).
   		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
   	}

以创建internalAutoProxyCreator的BeanPostProcessor [AnnotationAwareAspectJAutoProxyCreator]为例
    1) 创建Bean实例
    2) populateBean,为其属性赋值
    3) initializeBean,初始化Bean
      <1> invokeAwareMethods:一系列Aware接口的检查,若实现则注入相应的底层组件,AnnotationAwareAspectJAutoProxyCreator的父类逻辑AbstractAdvisorAutoProxyCreator#setBeanFactory()在此被调用,AnnotationAwareAspectJAutoProxyCreator#initBeanFactory()又在setBeanFactory()中被调用

   	@Override
   	protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   		super.initBeanFactory(beanFactory);
   		if (this.aspectJAdvisorFactory == null) {
   			this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
   		}
   		this.aspectJAdvisorsBuilder =
   				new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
   	}

      <2>applyBeanPostProcessorsBeforeInitialization
      <3> invokeInitMethods
      <4> applyBeanPostProcessorsAfterInitialization
   4) 加入集合,【排序,】注册至BeanFactory

   	/**
   	 * Register the given BeanPostProcessor beans.
   	 */
   	private static void registerBeanPostProcessors(
   			ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

   		for (BeanPostProcessor postProcessor : postProcessors) {
   			beanFactory.addBeanPostProcessor(postProcessor);
   		}
   	}

   以上是创建并注册AnnotationAwareAspectJAutoProxyCreator(另一种后置处理器InstantiationAwareBeanPostProcessor)的过程,注册完成后,其将作用于所有之后 创建的Bean的前后 (注意:不是初始化前后)


   [4] 在[3]完成后执行finishBeanFactoryInitialization(beanFactory),完成BeanFactory初始化工作,即创建并注册剩下的单实例Bean: beanFactory.preInstantiateSingletons()
      遍历获取容器中所有beanDefinitionNames,依次创建对象getBean(beanName) -> doGetBean(…) -> getSingleton(…) [先从缓存中获取当前Bean,若能取到则说明之前已被创建,直接使用,否则新建并置入缓存] -> getObject(…) -> createBean(…) -> resolveBeforeInstantiation(…)[希望后置处理器返回一个代理对象applyBeanPostProcessorBeforeInstantiation/applyBeanPostProcessorAfterInitialization,若能返回则使用,否则再调用doCreateBean]

   	/**
   	 * Central method of this class: creates a bean instance,
   	 * populates the bean instance, applies post-processors, etc.
   	 * @see #doCreateBean
   	 */
   	@Override
   	protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
   		if (logger.isDebugEnabled()) {
   			logger.debug("Creating instance of bean '" + beanName + "'");
   		}
   		RootBeanDefinition mbdToUse = mbd;

   		// Make sure bean class is actually resolved at this point, and
   		// clone the bean definition in case of a dynamically resolved Class
   		// which cannot be stored in the shared merged bean definition.
   		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
   		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
   			mbdToUse = new RootBeanDefinition(mbd);
   			mbdToUse.setBeanClass(resolvedClass);
   		}

   		// Prepare method overrides.
   		try {
   			mbdToUse.prepareMethodOverrides();
   		}
   		catch (BeanDefinitionValidationException ex) {
   			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
   					beanName, "Validation of method overrides failed", ex);
   		}

   		try {
   			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
   			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
   			if (bean != null) {
   				return bean;
   			}
   		}
   		catch (Throwable ex) {
   			throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
   					"BeanPostProcessor before instantiation of bean failed", ex);
   		}

   		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
   		if (logger.isDebugEnabled()) {
   			logger.debug("Finished creating instance of bean '" + beanName + "'");
   		}
   		return beanInstance;
   	}


   	/**
   	 * Apply before-instantiation post-processors, resolving whether there is a
   	 * before-instantiation shortcut for the specified bean.
   	 * @param beanName the name of the bean
   	 * @param mbd the bean definition for the bean
   	 * @return the shortcut-determined bean instance, or {@code null} if none
   	 */
   	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
   		Object bean = null;
   		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
   			// Make sure bean class is actually resolved at this point.
   			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;
   	}

   	/**
   	 * Apply InstantiationAwareBeanPostProcessors to the specified bean definition
   	 * (by class and name), invoking their {@code postProcessBeforeInstantiation} methods.
   	 * <p>Any returned object will be used as the bean instead of actually instantiating
   	 * the target bean. A {@code null} return value from the post-processor will
   	 * result in the target bean being instantiated.
   	 * @param beanClass the class of the bean to be instantiated
   	 * @param beanName the name of the bean
   	 * @return the bean object to use instead of a default instance of the target bean, or {@code null}
   	 * @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
   	 */
   	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;
   	}

结论:AnnotationAspectJAutoProxyCreator会在任何Bean创建之前先尝试返回实例(拦截)

AbstractAutoProxyCreator#具备业务逻辑的后置处理器相关(AnnotationAwareAspectJAutoProxyCreator的作用)
   	/**
   	 * 每一个Bean创建之前调用
   	 */
   	@Override
   	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
   		Object cacheKey = getCacheKey(beanClass, beanName);

   		if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
             	//判断当前Bean是否存在于advisedBeans(保存所有需要增强的Bean)
   			if (this.advisedBeans.containsKey(cacheKey)) {
   				return null;
   			}
             	//【判断1】判断当前Bean的类型是否为“基础类型Advice/Pointcut/Advisor/AopInfrastructureBean” 或者 是否为切面(@Aspect)
             	//【判断2】是否需要跳过
   			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
   				this.advisedBeans.put(cacheKey, Boolean.FALSE);
   				return null;
   			}
   		}

   		// Create proxy here if we have a custom TargetSource.
   		// Suppresses unnecessary default instantiation of the target bean:
   		// The TargetSource will handle target instances in a custom fashion.
   		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;
   	}


   	/**
   	 * 每一个Bean初始化后调用
   	 * Create a proxy with the configured interceptors if the bean is
   	 * identified as one to proxy by the subclass.
   	 * @see #getAdvicesAndAdvisorsForBean
   	 */
   	@Override
   	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;
   	}

   	/**
   	 * Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
   	 * @param bean the raw bean instance
   	 * @param beanName the name of the bean
   	 * @param cacheKey the cache key for metadata access
   	 * @return a proxy wrapping the bean, or the raw bean instance as-is
   	 */
   	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;
   		}
   		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
   			this.advisedBeans.put(cacheKey, Boolean.FALSE);
   			return bean;
   		}

   		// Create proxy if we have advice.[KEY]
         	 // 获取当前Bean的所有增强器(通知方法):从候选增强器中找到可以在当前Bean上使用的增强器的排序数组(AopUtils#findAdvisorsThatCanApply查找哪些通知方法需要切入当前Bean的方法)
   		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   		if (specificInterceptors != DO_NOT_PROXY) {
             	//保存当前Bean在advisedBeans,表示已被处理
   			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;
   	}


   	/**
   	 * Create an AOP proxy for the given bean.
   	 * @param beanClass the class of the bean
   	 * @param beanName the name of the bean
   	 * @param specificInterceptors the set of interceptors that is
   	 * specific to this bean (may be empty, but not null)
   	 * @param targetSource the TargetSource for the proxy,
   	 * already pre-configured to access the bean
   	 * @return the AOP proxy for the bean
   	 * @see #buildAdvisors
   	 */
   	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);
   			}
   		}
   		//获取所有的增强器添加至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());
   	}

   	/**
   	 * Return whether the given bean class represents an infrastructure class
   	 * that should never be proxied.
   	 * <p>The default implementation considers Advices, Advisors and
   	 * AopInfrastructureBeans as infrastructure classes.
   	 * @param beanClass the class of the bean
   	 * @return whether the bean represents an infrastructure class
   	 * @see org.aopalliance.aop.Advice
   	 * @see org.springframework.aop.Advisor
   	 * @see org.springframework.aop.framework.AopInfrastructureBean
   	 * @see #shouldSkip
   	 */
   	protected boolean isInfrastructureClass(Class<?> beanClass) {
   		boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
   				Pointcut.class.isAssignableFrom(beanClass) ||
   				Advisor.class.isAssignableFrom(beanClass) ||
   				AopInfrastructureBean.class.isAssignableFrom(beanClass);
   		if (retVal && logger.isTraceEnabled()) {
   			logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
   		}
   		return retVal;
   	}


   	/**
   	 * 子类AnnotationAwareAspectJAutoProxyCreator重写上面方法【实际调用】
   	 */
   	@Override
   	protected boolean isInfrastructureClass(Class<?> beanClass) {
   		// Previously we setProxyTargetClass(true) in the constructor, but that has too
   		// broad an impact. Instead we now override isInfrastructureClass to avoid proxying
   		// aspects. I'm not entirely happy with that as there is no good reason not
   		// to advise aspects, except that it causes advice invocation to go through a
   		// proxy, and if the aspect implements e.g the Ordered interface it will be
   		// proxied by that interface and fail at runtime as the advice method is not
   		// defined on the interface. We could potentially relax the restriction about
   		// not advising aspects in the future.
   		return (super.isInfrastructureClass(beanClass) || this.aspectJAdvisorFactory.isAspect(beanClass));
   	}

   	/**
   	 *子类AnnotationAwareAspectJAutoProxyCreator重写方法【实际调用】
   	 */
   	@Override
   	protected boolean shouldSkip(Class<?> beanClass, String beanName) {
   		// TODO: Consider optimization by caching the list of the aspect names
         	 // 获取候选的增强器(切面中的通知方法)集合,每一个增强器是InstantionModelAwarePointcutAdvisor
   		List<Advisor> candidateAdvisors = findCandidateAdvisors();
   		for (Advisor advisor : candidateAdvisors) {
   			if (advisor instanceof AspectJPointcutAdvisor) {
   				if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {
   					return true;
   				}
   			}
   		}
         	//Super version returns false
   		return super.shouldSkip(beanClass, beanName);
   	}
   //org.springframework.aop.framework.DefaultAopProxyFactory
   	@Override
   	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)) {
                 	 //原生Jdk基于接口的动态代理
   				return new JdkDynamicAopProxy(config);
   			}
             	//cglib基于类的动态代理
   			return new ObjenesisCglibAopProxy(config);
   		}
   		else {
   			return new JdkDynamicAopProxy(config);
   		}
   	}

3. 代理对象执行目标方法

(1) 容器保存组件的代理对象(增强后的对象),其中保存了一系列详细信息(比如增强器、目标对象…)
AdviceProxy
(2) CglibAopProxy#DynamicAdvisedInterceptor#intercept()

		@Override
		public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
			Object oldProxy = null;
			boolean setProxyContext = false;
			Class<?> targetClass = null;
			Object target = null;
			try {
				if (this.advised.exposeProxy) {
					// Make invocation available if necessary.
					oldProxy = AopContext.setCurrentProxy(proxy);
					setProxyContext = true;
				}
				// May be null. Get as late as possible to minimize the time we
				// "own" the target, in case it comes from a pool...
				target = getTarget();
				if (target != null) {
					targetClass = target.getClass();
				}
              	//1. 获取将要执行的目标方法拦截器链 [KEY]
				List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
				Object retVal;
				// Check whether we only have one InvokerInterceptor: that is,
				// no real advice, but just reflective invocation of the target.
              	 //2. 如果没有拦截器链,直接执行目标方法
				if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
					// We can skip creating a MethodInvocation: just invoke the target directly.
					// Note that the final invoker must be an InvokerInterceptor, so we know
					// it does nothing but a reflective operation on the target, and no hot
					// swapping or fancy proxying.
					Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
					retVal = methodProxy.invoke(target, argsToUse);
				}
				else {
					// We need to create a method invocation...
                      //3. 如果由拦截器链,则使用需要执行的目标对象,目标方法,拦截器链等信息初始化一个CglibMethodInvocation,并调用proceed放行
					retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
				}
				retVal = processReturnType(proxy, target, method, retVal);
				return retVal;
			}
			finally {
				if (target != null) {
					releaseTarget(target);
				}
				if (setProxyContext) {
					// Restore old proxy.
					AopContext.setCurrentProxy(oldProxy);
				}
			}
		}

(3) 拦截器链的获取过程
   <1>List<Object> interceptorList 保存所有拦截器(1+n),1个默认的ExposeInvocationInterceptor和n个自定义的增强器Advisor
   <2>遍历所有增强器,将其转换为Interceptor,registry.getInterceptors(advisor),得到拦截器链

//org.springframework.aop.framework.DefaultAdvisorChainFactory

	@Override
	public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, Class<?> targetClass) {

		// This is somewhat tricky... We have to process introductions first,
		// but we need to preserve order in the ultimate list.
		List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
		Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
		boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
		AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

		for (Advisor advisor : config.getAdvisors()) {
			if (advisor instanceof PointcutAdvisor) {
				// Add it conditionally.
				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
				if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
					MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
					if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
						if (mm.isRuntime()) {
							// Creating a new object instance in the getInterceptors() method
							// isn't a problem as we normally cache created chains.
							for (MethodInterceptor interceptor : interceptors) {
								interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
							}
						}
						else {
							interceptorList.addAll(Arrays.asList(interceptors));
						}
					}
				}
			}
			else if (advisor instanceof IntroductionAdvisor) {
				IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
				if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
					Interceptor[] interceptors = registry.getInterceptors(advisor);
					interceptorList.addAll(Arrays.asList(interceptors));
				}
			}
			else {
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			}
		}

		return interceptorList;
	}
//org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry

	@Override
	public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
		List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
		Advice advice = advisor.getAdvice();
      	//如果是MethodInterceptor则直接加入到集合中
		if (advice instanceof MethodInterceptor) {
			interceptors.add((MethodInterceptor) advice);
		}
        //如果不是,使用AdvisorAdapter将增强其转为MethodInterceptor(针对切面的通知)
		for (AdvisorAdapter adapter : this.adapters) {
			if (adapter.supportsAdvice(advice)) {
				interceptors.add(adapter.getInterceptor(advisor));
			}
		}
		if (interceptors.isEmpty()) {
			throw new UnknownAdviceTypeException(advisor.getAdvice());
		}
         //返回MethodInterceptor数组
		return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
	}

(4) 拦截器链触发 proceed

//org.springframework.aop.framework.ReflectiveMethodInvocation

	@Override
	public Object proceed() throws Throwable {
		//	We start with an index of -1 and increment early.
         //  【情况一】没有拦截器链时,0-1=-1,直接反射调用目标方法
      	 //	 【情况二】到了最后一个拦截器
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
				return dm.interceptor.invoke(this);
			}
			else {
				// Dynamic matching failed.
				// Skip this interceptor and invoke the next in the chain.
				return proceed();
			}
		}
		else {
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

	/**
	 * Invoke the joinpoint using reflection.
	 * Subclasses can override this to use custom invocation.
	 * @return the return value of the joinpoint
	 * @throws Throwable if invoking the joinpoint resulted in an exception
	 */
	protected Object invokeJoinpoint() throws Throwable {
		return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
	}
//org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(MethodInvocation)

	/*
	 *	private static final ThreadLocal<MethodInvocation> invocation =
			new NamedThreadLocal<MethodInvocation>("Current AOP method invocation");
	 */
	@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		MethodInvocation oldInvocation = invocation.get();
		invocation.set(mi);
		try {
             //以ExposeInvocationInterceptor为例
             //所有拦截器都会再调用proceed进行递归,当满足【情况二】后向逐层向上返回,切面方法将在调用proceed的前后进行调用,比如this.advice.before(mi.getMethod(),mi.getArguments(),mi.getThis());
			return mi.proceed();
		}
		finally {
			invocation.set(oldInvocation);
		}
	}

【AOP总结】

  1. @EnableAspectJAutoProxy 开启AOP功能
  2. 原理:向容器中注册一个关键组件AnnotationAwareAspectJProxyCreator
  3. AnnotationAwareAspectJAutoProxyCreator是一个后置处理器
  4. 容器的创建流程:
    (1) registerBeanPostProcessors() 注册后置处理器,创建AnnotationAwareAspectJAutoProxyCreator
    (2) finishBeanFactoryInitialization() 初始化剩下的单实例Bean
       创建业务组件和切面组件
       AnnotationAwareAspectJAutoProxyCreator拦截其余组件的创建
       创建完成后,判断组件是否需要增强,若需要则将切面的通知方法包装为增强器Advisor,为业务逻辑组件创建一个代理对象
  5. 执行目标方法
    (1) 代理对象执行目标方法
    (2) CglibAopProxy.intercept()
       得到目标方法的拦截器链(Advisor->Interceptor)
       链式机制,向下递归执行,向上逐层返回

猜你喜欢

转载自blog.csdn.net/weixin_38240095/article/details/86494804
今日推荐