概述
DefaultAdvisorAutoProxyCreator
是Spring AOP
内置的一个APC
,它在容器每个bean
初始化的后置处理阶段,从容器中找到所有的Spring Advisor bean
,然后检测这些Advisor bean
是否需要包裹到容器正在初始化的bean
上。
DefaultAdvisorAutoProxyCreator
要用的拦截器都来自于容器中匹配的Spring Advisors
,而不考虑其他方式定义的aspects
。
DefaultAdvisorAutoProxyCreator
过滤某个Spring Advisor
是否符合条件的方法isEligibleAdvisorBean
覆盖了基类中的缺省实现。它有两种工作模式 :
- 不使用
Advisor bean
名称前缀匹配方式 : 这种方式下认为每个Advisor
都符合条件; - 使用
Advisor bean
名称前缀匹配方式 : 这种方式下认为仅仅Advisor bean
名称符合指定前缀的Advisor
才符合条件;
当前,符合以上isEligibleAdvisorBean
条件的Advisor
并不是都会应用到该APC
当前所处理的bean
上,还会根据bean
类/方法上的注解考虑是否包裹一个Advisor
。
源代码
源代码版本 : spring-aop-5.1.5.RELEASE
package org.springframework.aop.framework.autoproxy;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.lang.Nullable;
/**
* BeanPostProcessor implementation that creates AOP proxies based on all
* candidate Advisors in the current BeanFactory. This class is
* completely generic; it contains no special code to handle any particular aspects,
* such as pooling aspects.
*
* It's possible to filter out advisors - for example, to use multiple post processors
* of this type in the same factory - by setting the usePrefix property to true,
* in which case only advisors beginning with the DefaultAdvisorAutoProxyCreator's bean
* name followed by a dot (like "aapc.") will be used. This default prefix can be changed
* from the bean name by setting the advisorBeanNamePrefix property.
* The separator (.) will also be used in this case.
*
* @author Rod Johnson
* @author Rob Harrop
*/
@SuppressWarnings("serial")
public class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator implements BeanNameAware {
/** Separator between prefix and remainder of bean name. */
public static final String SEPARATOR = ".";
private boolean usePrefix = false;
@Nullable
private String advisorBeanNamePrefix;
/**
* Set whether to only include advisors with a certain prefix in the bean name.
* Default is false, including all beans of type Advisor.
* @see #setAdvisorBeanNamePrefix
*/
public void setUsePrefix(boolean usePrefix) {
this.usePrefix = usePrefix;
}
/**
* Return whether to only include advisors with a certain prefix in the bean name.
*/
public boolean isUsePrefix() {
return this.usePrefix;
}
/**
* Set the prefix for bean names that will cause them to be included for
* auto-proxying by this object. This prefix should be set to avoid circular
* references. Default value is the bean name of this object + a dot.
* @param advisorBeanNamePrefix the exclusion prefix
*/
public void setAdvisorBeanNamePrefix(@Nullable String advisorBeanNamePrefix) {
this.advisorBeanNamePrefix = advisorBeanNamePrefix;
}
/**
* Return the prefix for bean names that will cause them to be included
* for auto-proxying by this object.
*/
@Nullable
public String getAdvisorBeanNamePrefix() {
return this.advisorBeanNamePrefix;
}
@Override
public void setBeanName(String name) {
// If no infrastructure bean name prefix has been set, override it.
if (this.advisorBeanNamePrefix == null) {
this.advisorBeanNamePrefix = name + SEPARATOR;
}
}
/**
* Consider Advisor beans with the specified prefix as eligible, if activated.
* @see #setUsePrefix
* @see #setAdvisorBeanNamePrefix
*/
@Override
protected boolean isEligibleAdvisorBean(String beanName) {
// 使用该方法判断某个 Spring Advisor bean, bean 名称为 beanName 是否是符合条件的
// Advisor
if (!isUsePrefix()) {
// 如果不使用前缀匹配机制,则认为 beanName 对应的 Advisor 总是符合条件
return true;
}
// 如果使用前缀匹配机制,则仅在前缀匹配时才认为当前 Advisor bean 符合条件
String prefix = getAdvisorBeanNamePrefix();
return (prefix != null && beanName.startsWith(prefix));
}
}