Spring BeanPostProcessor : AnnotationAwareAspectJAutoProxyCreator

概述

BeanPostProcessor AnnotationAwareAspectJAutoProxyCreator的作用如下 :

  1. 获取当前应用上下文中所有使用@AspectJ注解的切面类中的advice方法和所有Spring Advisor bean

    获取所有advice方法/advisor的任务在AnnotationAwareAspectJAutoProxyCreator应用到每个bean创建时执行,但内部使用了缓存机制,所以真正的查找过程只发生在第一次被调用时。

  2. 在每个bean创建时检测该bean是否符合创建代理的条件,如果符合,则获取可以应用在该bean上的所有advise,为当前bean生成一个代理对象。

    是否符合条件的主要判断逻辑为AopUtils#findAdvisorsThatCanApply

如果使用了aop:include,那么只有名称符合该include条件的@AspectJ注解bean才会被用于定义切面。

源代码分析

源代码版本 : spring-aop-5.1.5.RELEASE

AnnotationAwareAspectJAutoProxyCreator源代码

package org.springframework.aop.aspectj.annotation;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

@SuppressWarnings("serial")
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {

	@Nullable
	private List<Pattern> includePatterns;

	@Nullable
	private AspectJAdvisorFactory aspectJAdvisorFactory;

	@Nullable
	private BeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;


	/**
	 * Set a list of regex patterns, matching eligible @AspectJ bean names.
	 * Default is to consider all @AspectJ beans as eligible.
	 */
	public void setIncludePatterns(List<String> patterns) {
		this.includePatterns = new ArrayList<>(patterns.size());
		for (String patternText : patterns) {
			this.includePatterns.add(Pattern.compile(patternText));
		}
	}

	public void setAspectJAdvisorFactory(AspectJAdvisorFactory aspectJAdvisorFactory) {
		Assert.notNull(aspectJAdvisorFactory, "AspectJAdvisorFactory must not be null");
		this.aspectJAdvisorFactory = aspectJAdvisorFactory;
	}

	@Override
	protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 使用基类方法初始化 beanFactory,真正的逻辑时构造一个能够从容器中获取所有
		// Spring Advisor bean的BeanFactoryAdvisorRetrievalHelper
		super.initBeanFactory(beanFactory);

		// 下面的逻辑是构造 aspectJAdvisorsBuilder , 用于通过反射方法从容器中获取
		// 所有带有@AspectJ注解的 beans
		if (this.aspectJAdvisorFactory == null) {
			this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
		}
		this.aspectJAdvisorsBuilder =
				new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
	}


	// 找到容器中所有的Spring Advisor beans 和 @AspectJ 注解的 beans,都封装成
	// Advisor 形式返回一个列表
	@Override
	protected List<Advisor> findCandidateAdvisors() {
		// Add all the Spring advisors found according to superclass rules.
		// 使用基类Spring Advisor查找机制查找容器中所有的Spring Advisor
		// 其实就是父类使用所构造的BeanFactoryAdvisorRetrievalHelper从
		// 容器中获取所有的Spring Advisor beans。
		List<Advisor> advisors = super.findCandidateAdvisors();
		// Build Advisors for all AspectJ aspects in the bean factory.
		// 使用aspectJAdvisorsBuilder从容器中获取所有@AspectJ 注解的bean,并将它们
		// 包装成Advisor
		if (this.aspectJAdvisorsBuilder != null) {
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}

		// 现在列表advisors包含容器中所有的Spring Advisor beans 和 @AspectJ 注解的 beans,
		// 现在它们都以 Advisor 的形式存在
		return advisors;
	}

	// 判断指定的类是否是一个基础设置类:
	// 1. 如果父类的 isInfrastructureClass 断定它是一个基础设施类,就认为它是;
	// 2. 如果这是一个@Aspect注解的类,也认为这是一个基础设施类;
	// 一旦某个bean类被认为是基础设施类,那么将不会对该类实施代理机制	
	@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 != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
	}

	/**
	 * Check whether the given aspect bean is eligible for auto-proxying.
	 * If no aop:include elements were used then "includePatterns" will be
	 * null and all beans are included. If "includePatterns" is non-null,
	 * then one of the patterns must match.
	 * 检查给定名称的bean是否是符合条件的Aspect bean。这里是依据属性 includePatterns 做检查的,
	 * 当 includePatterns 属性为 null 时,总是返回 true。
	 */
	protected boolean isEligibleAspectBean(String beanName) {
		if (this.includePatterns == null) {
			return true;
		}
		else {
			for (Pattern pattern : this.includePatterns) {
				if (pattern.matcher(beanName).matches()) {
					return true;
				}
			}
			return false;
		}
	}


	/**
	 * Subclass of BeanFactoryAspectJAdvisorsBuilderAdapter that delegates to
	 * surrounding AnnotationAwareAspectJAutoProxyCreator facilities.
	 */
	private class BeanFactoryAspectJAdvisorsBuilderAdapter extends BeanFactoryAspectJAdvisorsBuilder {

		public BeanFactoryAspectJAdvisorsBuilderAdapter(
				ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {

			super(beanFactory, advisorFactory);
		}

		@Override
		protected boolean isEligibleBean(String beanName) {
			return AnnotationAwareAspectJAutoProxyCreator.this.isEligibleAspectBean(beanName);
		}
	}

}

从上面AnnotationAwareAspectJAutoProxyCreator可见,它主要是对注解@Aspect做了一些基于基类的增强,自身所实施功能很少,我们继续分析其基类AspectJAwareAdvisorAutoProxyCreator/AbstractAdvisorAutoProxyCreator/AbstractAutoProxyCreator

基类AspectJAwareAdvisorAutoProxyCreator 源代码

package org.springframework.aop.aspectj.autoproxy;

// 省略 imports

@SuppressWarnings("serial")
public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {

	private static final Comparator<Advisor> DEFAULT_PRECEDENCE_COMPARATOR = new AspectJPrecedenceComparator();

	/**
	 * Sort the rest by AspectJ precedence. If two pieces of advice have
	 * come from the same aspect they will have the same order.
	 * Advice from the same aspect is then further ordered according to the
	 * following rules:
	 * 
	 * 1. if either of the pair is after advice, then the advice declared
	 * last gets highest precedence (runs last)
	 * 2. otherwise the advice declared first gets highest precedence (runs first)
	 * 
	 * Important : Advisors are sorted in precedence order, from highest
	 * precedence to lowest. "On the way in" to a join point, the highest precedence
	 * advisor should run first. "On the way out" of a join point, the highest precedence
	 * advisor should run last.
	 */
	@Override
	@SuppressWarnings("unchecked")
	protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
		List<PartiallyComparableAdvisorHolder> partiallyComparableAdvisors = new ArrayList<>(advisors.size());
		for (Advisor element : advisors) {
			partiallyComparableAdvisors.add(
					new PartiallyComparableAdvisorHolder(element, DEFAULT_PRECEDENCE_COMPARATOR));
		}
		List<PartiallyComparableAdvisorHolder> sorted = PartialOrder.sort(partiallyComparableAdvisors);
		if (sorted != null) {
			List<Advisor> result = new ArrayList<>(advisors.size());
			for (PartiallyComparableAdvisorHolder pcAdvisor : sorted) {
				result.add(pcAdvisor.getAdvisor());
			}
			return result;
		}
		else {
			return super.sortAdvisors(advisors);
		}
	}

	/**
	 * Adds an ExposeInvocationInterceptor to the beginning of the advice chain.
	 * These additional advices are needed when using AspectJ expression pointcuts
	 * and when using AspectJ-style advice.
	 * 往 advice chain, 也就是这个candidateAdvisors的开头增加一个ExposeInvocationInterceptor实例,
	 * 在使用 AspectJ pointcut 表达式 和 AspectJ风格的advice 时用得到这个Interceptor
	 */
	@Override
	protected void extendAdvisors(List<Advisor> candidateAdvisors) {
		// 具体添加动作交给工具类 AspectJProxyUtils 处理
		AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
	}

	@Override
	protected boolean shouldSkip(Class<?> beanClass, String beanName) {
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		for (Advisor advisor : candidateAdvisors) {
			if (advisor instanceof AspectJPointcutAdvisor &&
					((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
				return true;
			}
		}
		return super.shouldSkip(beanClass, beanName);
	}


	/**
	 * Implements AspectJ PartialComparable interface for defining partial orderings.
	 */
	private static class PartiallyComparableAdvisorHolder implements PartialComparable {

		private final Advisor advisor;

		private final Comparator<Advisor> comparator;

		public PartiallyComparableAdvisorHolder(Advisor advisor, Comparator<Advisor> comparator) {
			this.advisor = advisor;
			this.comparator = comparator;
		}

		@Override
		public int compareTo(Object obj) {
			Advisor otherAdvisor = ((PartiallyComparableAdvisorHolder) obj).advisor;
			return this.comparator.compare(this.advisor, otherAdvisor);
		}

		@Override
		public int fallbackCompareTo(Object obj) {
			return 0;
		}

		public Advisor getAdvisor() {
			return this.advisor;
		}

		@Override
		public String toString() {
			StringBuilder sb = new StringBuilder();
			Advice advice = this.advisor.getAdvice();
			sb.append(ClassUtils.getShortName(advice.getClass()));
			sb.append(": ");
			if (this.advisor instanceof Ordered) {
				sb.append("order ").append(((Ordered) this.advisor).getOrder()).append(", ");
			}
			if (advice instanceof AbstractAspectJAdvice) {
				AbstractAspectJAdvice ajAdvice = (AbstractAspectJAdvice) advice;
				sb.append(ajAdvice.getAspectName());
				sb.append(", declaration order ");
				sb.append(ajAdvice.getDeclarationOrder());
			}
			return sb.toString();
		}
	}

}

该基类主要实现了advice的排序,是否要跳过,以及扩展增加ExposeInvocationInterceptor的工具功能,真正的BeanPostProcessor回调功能仍需要继续分析基类。

基类AbstractAdvisorAutoProxyCreator源代码

AbstractAdvisorAutoProxyCreator是一个通用的自动代理创建器,其设计目的就是检测每个bean上适用的Advisor并据此为该bean创建AOP代理。该类的子类可以重写方法findCandidateAdvisors()用于查找容器中所有的Advisor,这些Advisor有可能用于每个bean(是否真正适用,取决于匹配条件,比如通过所定义的pointcut表达式求值匹配等手段)。子类也可以重写方法shouldSkip()决定是否要排除对某些bean创建代理。

package org.springframework.aop.framework.autoproxy;

// 省略 import 行

@SuppressWarnings("serial")
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {

	@Nullable
	private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;


	// 覆盖基类的setBeanFactory方法
	@Override
	public void setBeanFactory(BeanFactory beanFactory) {
		// 首先调用基类的setBeanFactory方法
		super.setBeanFactory(beanFactory);

		// 要求所设置的 beanFactory 也就是Spring bean容器必须使用类型 ConfigurableListableBeanFactory,
		// 否则抛出异常,声明当前 AdvisorAutoProxyCreator 只针对类型为 ConfigurableListableBeanFactory
		// 的容器工作
		if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
			throw new IllegalArgumentException(
					"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
		}
	
		// 上面设置完beanFactory检查过类型之后,立即初始化 beanFactory,初始化逻辑 :
		// 准备一个针对该beanFactory的BeanFactoryAdvisorRetrievalHelperAdapter记录到
		// this.advisorRetrievalHelper, 用于从beanFactory获取Spring Advisor。
		initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
	}

	// 初始化 beanFactory,初始化逻辑 :
	// 准备一个针对该beanFactory的BeanFactoryAdvisorRetrievalHelperAdapter记录到
	// this.advisorRetrievalHelper, 用于从beanFactory获取Spring Advisor。
	protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
	}


	// 找到针对某个bean的所有符合条件的Advisor/Advice,如果结果为null,将不会为该bean创建代理
	@Override
	@Nullable
	protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			// DO_NOT_PROXY 其实是一个为 null 的常量,用于表示:
			// 如果找不到符合条件的Advisor,就不要为该bean创建代理
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}

	/**
	 * Find all eligible Advisors for auto-proxying this class.
	 * @param beanClass the clazz to find advisors for
	 * @param beanName the name of the currently proxied bean
	 * @return the empty List, not null,
	 * if there are no pointcuts or interceptors
	 * @see #findCandidateAdvisors
	 * @see #sortAdvisors
	 * @see #extendAdvisors
	 */
	protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		// 使用 findCandidateAdvisors() 找到容器中所有的 Advisor : 
		// 可以参考当前类 findCandidateAdvisors() 的实现 : 仅获取容器中所有Spring Advisors
		// 或者参考 AnnotationAwareAspectJAutoProxyCreator 的实现 :
		// 获取容器中所有Spring Advisors + 所有封装自每个AspectJ切面类中的每个advice方法的Advisors
		List<Advisor> candidateAdvisors = findCandidateAdvisors();

		// 过滤所有找到的Advisor,看看它们对参数bean是否需要应用
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		// 对以上需要应用的advisor list作扩展,具体如何扩展,参考当前类或者子类对extendAdvisors()的具体实现
		// 当前类 extendAdvisors(): 什么都不做,只是个空方法
		// AnnotationAwareAspectJAutoProxyCreator#extendAdvisors():增加一个ExposeInvocationInterceptor
		extendAdvisors(eligibleAdvisors);
		
		if (!eligibleAdvisors.isEmpty()) {
			// 对适用的advisor做排序,具体排序方法参考sortAdvisors(),子类也可以定制该排序逻辑
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

	/**
	 * Find all candidate Advisors to use in auto-proxying.
	 * 该方法使用advisorRetrievalHelper找到容器中所有的Spring Advisor beans用于自动代理,
	 * 子类可以覆盖或者扩展该方法。
	 * @return the List of candidate Advisors
	 */
	protected List<Advisor> findCandidateAdvisors() {
		Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
		return this.advisorRetrievalHelper.findAdvisorBeans();
	}

	/**
	 * Search the given candidate Advisors to find all Advisors that
	 * can apply to the specified bean.
	 * @param candidateAdvisors the candidate Advisors
	 * @param beanClass the target's bean class
	 * @param beanName the target's bean name
	 * @return the List of applicable Advisors
	 * @see ProxyCreationContext#getCurrentProxiedBeanName()
	 */
	protected List<Advisor> findAdvisorsThatCanApply(
			List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

		// ProxyCreationContext 使用了一个 ThreadLocal 变量保持当前正在进行代理创建的bean,
		// 在代理创建过程中,比如对pointcut表达式求值时会使用到 ProxyCreationContext,
		// 由此可见,某个bean的代理创建必须在同一个线程内完成,不能跨线程
		ProxyCreationContext.setCurrentProxiedBeanName(beanName);
		try {
			// 具体检查每个advisor是否需要应用到该bean的逻辑委托给AopUtils完成,这里不做深入分析,			
			return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
		}
		finally {
			// 已经完成advisor和bean的匹配过程,清除ProxyCreationContext
			ProxyCreationContext.setCurrentProxiedBeanName(null);
		}
	}

	/**
	 * Return whether the Advisor bean with the given name is eligible
	 * for proxying in the first place.
	 * 返回某个bean是否需要被代理,这里是缺省实现,总是返回true,子类可以重写该方法实现
	 * 自己的定制逻辑
	 * @param beanName the name of the Advisor bean
	 * @return whether the bean is eligible
	 */
	protected boolean isEligibleAdvisorBean(String beanName) {
		return true;
	}

	/**
	 * Sort advisors based on ordering. Subclasses may choose to override this
	 * method to customize the sorting strategy.
	 * @param advisors the source List of Advisors
	 * @return the sorted List of Advisors
	 * @see org.springframework.core.Ordered
	 * @see org.springframework.core.annotation.Order
	 * @see org.springframework.core.annotation.AnnotationAwareOrderComparator
	 */
	protected List<Advisor> sortAdvisors(List<Advisor> advisors) {
		AnnotationAwareOrderComparator.sort(advisors);
		return advisors;
	}

	/**
	 * Extension hook that subclasses can override to register additional Advisors,
	 * given the sorted Advisors obtained to date.
	 * The default implementation is empty.
	 * Typically used to add Advisors that expose contextual information
	 * required by some of the later advisors.
	 * 提供给子类一个扩展candidateAdvisors的机会,至于如何扩展,看子类的目的
	 * @param candidateAdvisors the Advisors that have already been identified as
	 * applying to a given bean
	 */
	protected void extendAdvisors(List<Advisor> candidateAdvisors) {
	}

	/**
	 * This auto-proxy creator always returns pre-filtered Advisors.
	 */
	@Override
	protected boolean advisorsPreFiltered() {
		return true;
	}


	/**
	 * Subclass of BeanFactoryAdvisorRetrievalHelper that delegates to
	 * surrounding AbstractAdvisorAutoProxyCreator facilities.
	 * 自定义的一个BeanFactoryAdvisorRetrievalHelper,用于从容器中获取所有的 Spring Advisor
	 */
	private class BeanFactoryAdvisorRetrievalHelperAdapter extends BeanFactoryAdvisorRetrievalHelper {

		public BeanFactoryAdvisorRetrievalHelperAdapter(ConfigurableListableBeanFactory beanFactory) {
			super(beanFactory);
		}

		@Override
		protected boolean isEligibleBean(String beanName) {
			return AbstractAdvisorAutoProxyCreator.this.isEligibleAdvisorBean(beanName);
		}
	}

}

基类AbstractAutoProxyCreator源代码

package org.springframework.aop.framework.autoproxy;

// 省略 imports

@SuppressWarnings("serial")
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
		implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

	/**
	 * Convenience constant for subclasses: Return value for "do not proxy".
	 * @see #getAdvicesAndAdvisorsForBean
	 */
	@Nullable
	protected static final Object[] DO_NOT_PROXY = null;

	/**
	 * Convenience constant for subclasses: Return value for
	 * "proxy without additional interceptors, just the common ones".
	 * @see #getAdvicesAndAdvisorsForBean
	 */
	protected static final Object[] PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS = new Object[0];


	/** Logger available to subclasses. */
	protected final Log logger = LogFactory.getLog(getClass());

	/** Default is global AdvisorAdapterRegistry. */
	private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();

	/**
	 * Indicates whether or not the proxy should be frozen. Overridden from super
	 * to prevent the configuration from becoming frozen too early.
	 */
	private boolean freezeProxy = false;

	/** Default is no common interceptors. */
	private String[] interceptorNames = new String[0];

	private boolean applyCommonInterceptorsFirst = true;

	@Nullable
	private TargetSourceCreator[] customTargetSourceCreators;

	@Nullable
	private BeanFactory beanFactory;

	private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	private final Set<Object> earlyProxyReferences = 
		Collections.newSetFromMap(new ConcurrentHashMap<>(16));

	private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);

	private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);


	/**
	 * Set whether or not the proxy should be frozen, preventing advice
	 * from being added to it once it is created.
	 * 

Overridden from the super class to prevent the proxy configuration * from being frozen before the proxy is created. */ @Override public void setFrozen(boolean frozen) { this.freezeProxy = frozen; } @Override public boolean isFrozen() { return this.freezeProxy; } /** * Specify the AdvisorAdapterRegistry to use. *

Default is the global AdvisorAdapterRegistry. * @see org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry */ public void setAdvisorAdapterRegistry(AdvisorAdapterRegistry advisorAdapterRegistry) { this.advisorAdapterRegistry = advisorAdapterRegistry; } /** * Set custom TargetSourceCreators to be applied in this order. * If the list is empty, or they all return null, a SingletonTargetSource * will be created for each bean. * Note that TargetSourceCreators will kick in even for target beans * where no advices or advisors have been found. If a TargetSourceCreator * returns a TargetSource for a specific bean, that bean will be proxied * in any case. * TargetSourceCreators can only be invoked if this post processor is used * in a BeanFactory and its BeanFactoryAware callback is triggered. * @param targetSourceCreators the list of TargetSourceCreators. * Ordering is significant: The TargetSource returned from the first matching * TargetSourceCreator (that is, the first that returns non-null) will be used. */ public void setCustomTargetSourceCreators(TargetSourceCreator... targetSourceCreators) { this.customTargetSourceCreators = targetSourceCreators; } /** * Set the common interceptors. These must be bean names in the current factory. * They can be of any advice or advisor type Spring supports. *

If this property isn't set, there will be zero common interceptors. * This is perfectly valid, if "specific" interceptors such as matching * Advisors are all we want. */ public void setInterceptorNames(String... interceptorNames) { this.interceptorNames = interceptorNames; } /** * Set whether the common interceptors should be applied before bean-specific ones. * Default is "true"; else, bean-specific interceptors will get applied first. */ public void setApplyCommonInterceptorsFirst(boolean applyCommonInterceptorsFirst) { this.applyCommonInterceptorsFirst = applyCommonInterceptorsFirst; } @Override public void setBeanFactory(BeanFactory beanFactory) { this.beanFactory = beanFactory; } /** * Return the owning BeanFactory. * May be null, as this post-processor doesn't need to belong to a bean factory. */ @Nullable protected BeanFactory getBeanFactory() { return this.beanFactory; } @Override @Nullable public Class<?> predictBeanType(Class<?> beanClass, String beanName) { if (this.proxyTypes.isEmpty()) { return null; } Object cacheKey = getCacheKey(beanClass, beanName); return this.proxyTypes.get(cacheKey); } @Override @Nullable public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) { return null; } @Override public Object getEarlyBeanReference(Object bean, String beanName) { // 根据给定义的bean class 和 bean 名称构建一个 Cache 主键 Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { this.earlyProxyReferences.add(cacheKey); } return wrapIfNecessary(bean, beanName, cacheKey); } // InstantiationAwareBeanPostProcessor接口(BeanPostProcessor的子接口)定义的方法, // 在指定bean创建过程刚开始,尚未创建bean对象时,检查如果该bean需要创建代理,并且存在自定义 // TargetSource,基于TargetSource和匹配的advice/advisor为该bean创建代理对象 @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { // 根据给定义的bean class 和 bean 名称构建一个 Cache 主键 Object cacheKey = getCacheKey(beanClass, beanName); if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) { if (this.advisedBeans.containsKey(cacheKey)) { // 已经被该InstantiationAwareBeanPostProcessor的该方法处理过,这里不再处理 return null; } if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { // 该bean尚未被该bean该方法处理过, // 但如果是基础设施bean或者是需要被排除的bean,则将它们添加到缓存中,值为FALSE 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. TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { if (StringUtils.hasLength(beanName)) { this.targetSourcedBeans.add(beanName); } // 如果该bean存在TargetSource,在这里直接创建代理对象,而不再走主流程 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); // 这里返回非null proxy对象 return proxy; } // 这里返回 null , bean 创建尚未完成,主流程继续进行 return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) { return true; } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { return pvs; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { return 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(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } /** * Build a cache key for the given bean class and bean name. * Note: As of 4.2.3, this implementation does not return a concatenated * class/name String anymore but rather the most efficient cache key possible: * a plain bean name, prepended with BeanFactory#FACTORY_BEAN_PREFIX * in case of a FactoryBean or if no bean name specified, then the * given bean Class as-is. * 根据给定义的bean class 和 bean 名称构建一个 Cache 主键 * @param beanClass the bean class * @param beanName the bean name * @return the cache key for the given class and name */ protected Object getCacheKey(Class<?> beanClass, @Nullable String beanName) { if (StringUtils.hasLength(beanName)) { return (FactoryBean.class.isAssignableFrom(beanClass) ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName); } else { return beanClass; } } /** * 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 (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { // 这种情况说明该bean已经被处理过,参考方法 : #postProcessBeforeInstantiation return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { // 这种情况说明该bean已经被标记为不需要处理,参考方法 : #postProcessBeforeInstantiation return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. // 获取所有可以应用到该bean的 advice,通常是一组 Advisor 对象,每个 Advisor 可以相应地获得 // 一个 advice , 是接口 Interceptor 的某个实现类对象 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { // 该bean有可以应用的advice,这里需要创建相应的代理对象,现在先将该信息记录到缓存中 this.advisedBeans.put(cacheKey, Boolean.TRUE); // 创建当前bean的代理对象proxy Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } // 针对该bean没有可以应用的advice,将该信息记录到缓存 this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } /** * Return whether the given bean class represents an infrastructure class * that should never be proxied. * 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; } /** * Subclasses should override this method to return true if the * given bean should not be considered for auto-proxying by this post-processor. * Sometimes we need to be able to avoid this happening, e.g. if it will lead to * a circular reference or if the existing target instance needs to be preserved. * This implementation returns false unless the bean name indicates an * "original instance" according to AutowireCapableBeanFactory conventions. * @param beanClass the class of the bean * @param beanName the name of the bean * @return whether to skip the given bean * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#ORIGINAL_INSTANCE_SUFFIX */ protected boolean shouldSkip(Class<?> beanClass, String beanName) { return AutoProxyUtils.isOriginalInstance(beanName, beanClass); } /** * Create a target source for bean instances. Uses any TargetSourceCreators if set. * Returns null if no custom TargetSource should be used. * This implementation uses the "customTargetSourceCreators" property. * Subclasses can override this method to use a different mechanism. * @param beanClass the class of the bean to create a TargetSource for * @param beanName the name of the bean * @return a TargetSource for this bean * @see #setCustomTargetSourceCreators */ @Nullable protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) { // We can't create fancy target sources for directly registered singletons. if (this.customTargetSourceCreators != null && this.beanFactory != null && this.beanFactory.containsBean(beanName)) { for (TargetSourceCreator tsc : this.customTargetSourceCreators) { TargetSource ts = tsc.getTargetSource(beanClass, beanName); if (ts != null) { // Found a matching TargetSource. if (logger.isTraceEnabled()) { logger.trace("TargetSourceCreator [" + tsc + "] found custom TargetSource for bean with name '" + beanName + "'"); } return ts; } } } // No custom TargetSource found. return null; } /** * 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, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } // AOP 代理对象创建工厂类 ProxyFactory proxyFactory = new ProxyFactory(); // 从当前对象复制 ProxyConfig 信息 proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } // 构建最终适用于该bean的所有Advisor拦截器: // 1. 从容器获取通用拦截器 // 2. 加上仅仅适用于该bean的专用拦截器 : specificInterceptors Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); // 框架缺省使用this.freezeProxy为false proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(getProxyClassLoader()); } /** * Determine whether the given bean should be proxied with its target class rather than its interfaces. * Checks the AutoProxyUtils#PRESERVE_TARGET_CLASS_ATTRIBUTE "preserveTargetClass" attribute * of the corresponding bean definition. * @param beanClass the class of the bean * @param beanName the name of the bean * @return whether the given bean should be proxied with its target class * @see AutoProxyUtils#shouldProxyTargetClass */ protected boolean shouldProxyTargetClass(Class<?> beanClass, @Nullable String beanName) { return (this.beanFactory instanceof ConfigurableListableBeanFactory && AutoProxyUtils.shouldProxyTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName)); } /** * Return whether the Advisors returned by the subclass are pre-filtered * to match the bean's target class already, allowing the ClassFilter check * to be skipped when building advisors chains for AOP invocations. * Default is false. Subclasses may override this if they * will always return pre-filtered Advisors. * @return whether the Advisors are pre-filtered * @see #getAdvicesAndAdvisorsForBean * @see org.springframework.aop.framework.Advised#setPreFiltered */ protected boolean advisorsPreFiltered() { return false; } /** * Determine the advisors for the given bean, including the specific interceptors * as well as the common interceptor, all adapted to the Advisor interface. * @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) * @return the list of Advisors for the given bean */ protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) { // Handle prototypes correctly... // 获取通过#setInterceptorNames()设置的通用Advisors到commonInterceptors Advisor[] commonInterceptors = resolveInterceptorNames(); // 合并通用 commonInterceptors 和 专用 specificInterceptors (这里指针对某个bean专用) List<Object> allInterceptors = new ArrayList<>(); if (specificInterceptors != null) { allInterceptors.addAll(Arrays.asList(specificInterceptors)); if (commonInterceptors.length > 0) { if (this.applyCommonInterceptorsFirst) { allInterceptors.addAll(0, Arrays.asList(commonInterceptors)); } else { allInterceptors.addAll(Arrays.asList(commonInterceptors)); } } } if (logger.isTraceEnabled()) { int nrOfCommonInterceptors = commonInterceptors.length; int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0); logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors + " common interceptors and " + nrOfSpecificInterceptors + " specific interceptors"); } Advisor[] advisors = new Advisor[allInterceptors.size()]; for (int i = 0; i < allInterceptors.size(); i++) { advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i)); } return advisors; } /** * Resolves the specified interceptor names to Advisor objects. * @see #setInterceptorNames */ private Advisor[] resolveInterceptorNames() { BeanFactory bf = this.beanFactory; ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null); List<Advisor> advisors = new ArrayList<>(); for (String beanName : this.interceptorNames) { if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) { Assert.state(bf != null, "BeanFactory required for resolving interceptor names"); Object next = bf.getBean(beanName); advisors.add(this.advisorAdapterRegistry.wrap(next)); } } return advisors.toArray(new Advisor[0]); } /** * Subclasses may choose to implement this: for example, * to change the interfaces exposed. * The default implementation is empty. * @param proxyFactory a ProxyFactory that is already configured with * TargetSource and interfaces and will be used to create the proxy * immediately after this method returns */ protected void customizeProxyFactory(ProxyFactory proxyFactory) { } /** * Return whether the given bean is to be proxied, what additional * advices (e.g. AOP Alliance interceptors) and advisors to apply. * * 获取所有可以应用到该bean的 advice,通常是一组 Advisor 对象,每个 Advisor 可以相应地获得 * 一个 advice , 是接口 Interceptor 的某个实现类对象。由子类提供实现。 * * @param beanClass the class of the bean to advise * @param beanName the name of the bean * @param customTargetSource the TargetSource returned by the * #getCustomTargetSource method: may be ignored. * Will be null if no custom target source is in use. * @return an array of additional interceptors for the particular bean; * or an empty array if no additional interceptors but just the common ones; * or null if no proxy at all, not even with the common interceptors. * See constants DO_NOT_PROXY and PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS. * @throws BeansException in case of errors * @see #DO_NOT_PROXY * @see #PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS */ @Nullable protected abstract Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource customTargetSource) throws BeansException; }

总结

通过上述代码可以看出AnnotationAwareAspectJAutoProxyCreator对所设定任务的完成并不是完全通过该类自身,而是分散实现在各层次的基类中,尤其是基类AbstractAutoProxyCreator。综合来看,AnnotationAwareAspectJAutoProxyCreator实现了如下接口定义的方法 :

  • SmartInstantiationAwareBeanPostProcessor – 定义了方法getEarlyBeanReference
  • InstantiationAwareBeanPostProcessor – 定义了方法postProcessBeforeInstantiation
  • BeanPostProcessor – 定义了方法 postProcessAfterInitialization

如上接口定义的方法会在Spring约定的回调时机针对bean创建执行,而AnnotationAwareAspectJAutoProxyCreator或其基类为这些方法提供了实现。这些方法实现的主要逻辑针对一个目的 : 如果该bean匹配了容器中的某些advise,那么就为该bean创建相应的代理对象,这个代理对象可以理解为一组advice包裹着一个原始的bean对象。而创建代理对象的主要逻辑在基类AbstractAutoProxyCreator的如下两个方法 :

  • Object wrapIfNecessary(Object bean, String beanName, Object cacheKey)

    主要逻辑 : 如果需要创建代理,但是尚未创建代理,则获取适用的advices,调用createProxy创建代理

  • Object createProxy(Class beanClass, String beanName,Object[] specificInterceptors, TargetSource targetSource)

    主要逻辑 : 构建ProxyFactory对象,向其设置ProxyConfig代理配置参数,然后由该ProxyFactory对象创建代理对象

你可能感兴趣的:(spring,Spring,AOP,Spring,AOP,分析)