Spring 源码阅读 58:配置 ProxyFactory 的 Advisor 列表
概述
本文接着上一篇分析 Spring 创建 AOP 代理对象的createProxy方法。之前分析了 ProxyFactory 的创建、基础的配置参数,以及如何通过后处理器的配置和 Bean 类型实现的接口信息,来配置 ProxyFactory 的proxyTargetClass属性,这个属性决定了创建代理对象时是通过 JDK 动态代理的方式创建还是 CGLIB 方式创建。
构建 Advisor 列表
先回到createProxy方法的代码中。

本文开始分析下面的这部分:
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
首先,会调用buildAdvisors方法,构建一个 Advisor 列表,方法中的参数specificInterceptors就是在调用createProxy方法时传入的参数,也就是之前从 Spring 容器中找到的与当前 Bean 对象匹配的增强逻辑的集合。这里为什么还要构建一次 Advisor 的列表呢,我们进入方法查看。
buildAdvisors 方法
// org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#buildAdvisors
protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
// Handle prototypes correctly...
Advisor[] commonInterceptors = resolveInterceptorNames();
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;
}
先整体看一下这个方法的流程。首先,通过resolveInterceptorNames方法得到一个 Advisor 列表commonInterceptors,名称翻译过来就是普通拦截器。然后,将commonInterceptors和specificInterceptors都添加到实现声明的allInterceptors。最后,遍历allInterceptors中的元素,通过调用成员变量advisorAdapterRegistry的wrap方法处理成 Advisor 对象后,得到方法最终的结果。
接下来详细分析,先进入resolveInterceptorNames方法查看。
// org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#resolveInterceptorNames
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]);
}
这个方法中,会根据interceptorNames成员变量中保存的每一个拦截器名称,找到容器中对应的 Bean 实例,经过advisorAdapterRegistry的wrap方法的处理,得到最终返回的 Advisor 列表。
再看一下interceptorNames里有什么:
/** Default is no common interceptors. */
private String[] interceptorNames = new String[0];
可以看到,默认情况下这个数组是空的,并且advisorAdapterRegistry的wrap方法我们后面还会分析到,所以resolveInterceptorNames方法就分析到这里。
回到buildAdvisors方法中,接着往下看。
接下来,会将commonInterceptors和specificInterceptors合并为一个allInterceptors列表,合并时会进行判断,如果成员变量applyCommonInterceptorsFirst的值时true,则将commonInterceptors添加到allInterceptors头部,否则添加到尾部。这个属性的默认值是true。
方法的最后,会通过成员变量advisorAdapterRegistry的wrap方法来处理allInterceptors里的每一个拦截器。
advisorAdapterRegistry.wrap 方法
我们进入wrap方法。
@Override
public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
if (adviceObject instanceof Advisor) {
return (Advisor) adviceObject;
}
if (!(adviceObject instanceof Advice)) {
throw new UnknownAdviceTypeException(adviceObject);
}
Advice advice = (Advice) adviceObject;
if (advice instanceof MethodInterceptor) {
// So well-known it doesn't even need an adapter.
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
// Check that it is supported.
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
这个方法的逻辑比较简单,作用是将参数传入的拦截器对象(也就是上一步allInterceptors集合中的每一个元素)封装成 Advisor 对象。
如果当前操作的拦截器类型本身就是 Advisor 的实现类,那么,将其原样返回即可。如果它不是 Advisor 的实现类,那么在判断它是否是 Advice 的实现类,如果不是,则抛出异常,也就是说,它只能是 Advisor 或者 Advice 的实现类。
之后就是 Advice 的情况。先判断它是不是 MethodInterceptor 的实现类,MethodInterceptor 是 Advice 的子接口,如果是 MethodInterceptor 的实现类的话,则将其封装为 DefaultPointcutAdvisor 返回。
最后,对于是 Advice 实现类,但不是 MethodInterceptor 实现类的情况,在进行下面的逻辑处理。
遍历adapters成员变量中的每一个元素adapter,adapters中的内容可以从以下代码中看到:
private final List<AdvisorAdapter> adapters = new ArrayList<>(3);
/**
* Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.
*/
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
@Override
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
初始状态下,这里有三个 Advice 适配器。在遍历过程中对正在处理的 Advice 类型的拦截器,调用adapter的supportsAdvice方法,判断遍历到的适配器是不是与当前的拦截器适配,如果得到结果true,则将拦截器封装为 DefaultPointcutAdvisor 返回。如果adapters中没有能够预知适配的适配器,则表示无法将当前的拦截器包装成 Advisor,会在wrap方法的最后抛出异常。
其实适配器的supportsAdvice方法就是判断拦截器的类型。
介绍完wrap方法,buildAdvisors方法的全部流程也就介绍完了。在createProxy方法中,buildAdvisors的结果会被添加到proxyFactory的advisors结合中。
接下来,还将目标类型targetSource赋值给了proxyFactory的相应属性。
customizeProxyFactory 方法
设置完advisors和targetSource属性之后,执行了customizeProxyFactory方法。但这个方法是一个空方法。
protected void customizeProxyFactory(ProxyFactory proxyFactory) {
}
可以看出来,这是一个扩展点,通过在子类中重写这个方法,可以在 ProxyFactory 工厂对象的重要属性都配置完之后,在对其进行自定义的处理。
后续的步骤
接下来再看下一个代码片段。
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
这里又给proxyFactory配置了两个属性,其中if语句的判断条件中advisorsPreFiltered需要留意。
// org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#advisorsPreFiltered
protected boolean advisorsPreFiltered() {
return false;
}
在 AbstractAutoProxyCreator 中,这个方法返回了false。但是,我们这里用到的创建 AOP 代理的后处理器,并不是 AbstractAutoProxyCreator 类型,而是它的子类,所以需要找到子类中与具体实现类关系最近的类中的方法实现。可以找到 AbstractAdvisorAutoProxyCreator 找到重写的方法实现,返回的是true。
// org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#advisorsPreFiltered
@Override
protected boolean advisorsPreFiltered() {
return true;
}
在createProxy方法的最后,返回了通过调用proxyFactory的getProxy方法创建的代理对象。
return proxyFactory.getProxy(getProxyClassLoader());
具体的创建代理对象的原理,放到下篇文章中分析。
总结
本文分析了 Spring 创建 AOP 代理对象之前,初始化 ProxyFactory 对象的最后一部分逻辑,主要包含 Advisor 列表的构建。至此,可以看出,ProxyFactory 创建代理对象之前,最重要的配置内容就是创建代理对象的方式(JDK 动态代理或 CGLIB)以及增强逻辑的集合,接下来就进入了最后创建代理对象的过程。
转载自:https://juejin.cn/post/7157742171389427748