BeanPostProcessor
AnnotationAwareAspectJAutoProxyCreator
的作用如下 :
@AspectJ
注解的切面类中的advice
方法和所有Spring Advisor
bean
;
获取所有
advice
方法/advisor
的任务在AnnotationAwareAspectJAutoProxyCreator
应用到每个bean
创建时执行,但内部使用了缓存机制,所以真正的查找过程只发生在第一次被调用时。
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
对象创建代理对象