0%

引言

上篇文章 介绍了 SpringBoot 启动流程,本篇文章继续讲解接下来的流程 —— 容器刷新。

refresh() 方法

容器的刷新由 refreshContext(context) 调用触发,我们看下它的具体实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private void refreshContext(ConfigurableApplicationContext context) {
refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
}
catch (AccessControlException ex) {
// Not allowed in some environments.
}
}
}

/**
* Refresh the underlying {@link ApplicationContext}.
* @param applicationContext the application context to refresh
*/
protected void refresh(ApplicationContext applicationContext) {
Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
((AbstractApplicationContext) applicationContext).refresh();
}

refreshContext() 又调用了 refresh(context) 方法,同时这里也会容器注册关闭勾子(如果存在的话)。refresh 方法则是去调用容器的 refresh() 方法。从前一篇文章中,我们知道容器的实例为 AnnotationConfigServletWebServerApplicationContext,首先,我们看下它的继承关系图:



AnnotationConfigServletWebServerApplicationContext 继承了父类 ServletWebServerApplicationContextrefresh() 方法,我们看下方法实现:

1
2
3
4
5
6
7
8
9
10
@Override
public final void refresh() throws BeansException, IllegalStateException {
try {
super.refresh();
}
catch (RuntimeException ex) {
stopAndReleaseWebServer();
throw ex;
}
}

从代码中我们看到,这里会调用其父类的 refresh() 方法,而该方法就是 AbstractApplicationContextrefresh() 方法实现(这里我们看到,当发生异常时,则停止并实方 Web 服务):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备刷新
prepareRefresh();

// 让子类刷新内部的容器
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// 准备该上下文用到的容器
prepareBeanFactory(beanFactory);

try {
// 允许子类上下文对容器进行处理
postProcessBeanFactory(beanFactory);

// 调用容器的后置处理器
invokeBeanFactoryPostProcessors(beanFactory);

// 注册 bean 后置处理器
registerBeanPostProcessors(beanFactory);

// 配置国际化信息
initMessageSource();

// 事件广播器的初始化
initApplicationEventMulticaster();

// 调用子类的刷新方法
onRefresh();

// 注册监听器 bean
registerListeners();

// 实例化其余的非懒加载的 bean
finishBeanFactoryInitialization(beanFactory);

// 完成刷新,发布相关事件
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 摧毁创建好的 bean,避免资源悬挂
destroyBeans();
// 重置激活标记
cancelRefresh(ex);
throw ex;
}
finally {
// 重置 Spring 核心中的通用缓存,由于我们不再需要那些单例 bean 的元数据
resetCommonCaches();
}
}
}

我们很容易看出该方法其实是一个模板方法,其中相关流程都已经添加注释了,接下来我们一一介绍这些步骤。

准备刷新

准备刷新由 repareRefresh() 方法触发,我们看下代码:

1
2
3
4
5
@Override
protected void prepareRefresh() {
this.scanner.clearCache();
super.prepareRefresh();
}

AnnotationConfigServletWebServerApplicationContext 重写了父类的 prepareRefresh() 方法,其中增加了扫描器的缓存清除操作,之后便是调用父类的 prepareRefresh() 方法,即:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 /**
* 刷新前的准备工作,主要是设置启动日期、激活标记以及执行任何属性资源初始化器
*/
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);

if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}

// 初始化上下文环境变量中的属性源占位符
initPropertySources();

// 验证标记为必须的属性是否都可解析
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();

// 保存预刷新应用监听器
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// 重置本地应用监听器到预刷新状态
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}

// 允许早期应用事件在广播器可用时进行发布
this.earlyApplicationEvents = new LinkedHashSet<>();
}

initPropertySources() 是个空方法,AnnotationConfigServletWebServerApplicationContext 则继承了父类 GenericWebApplicationContext 的实现:

1
2
3
4
5
6
7
@Override
protected void initPropertySources() {
ConfigurableEnvironment env = getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment) env).initPropertySources(this.servletContext, null);
}
}

这里会从父类获取环境变量对象,如果是 Web 相关的,则调用 StandardServletEnvironmentinitPropertySources 方法进行初始化,而具体的实现则是由 WebApplicationContextUtils 来完成,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    /**
* Convenient variant of {@link #initServletPropertySources(MutablePropertySources,
* ServletContext, ServletConfig)} that always provides {@code null} for the
* {@link ServletConfig} parameter.
* @see #initServletPropertySources(MutablePropertySources, ServletContext, ServletConfig)
*/
public static void initServletPropertySources(MutablePropertySources sources,
@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {

Assert.notNull(sources, "'propertySources' must not be null");
String name = StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME;
if (servletContext != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
sources.replace(name, new ServletContextPropertySource(name, servletContext));
}
name = StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME;
if (servletConfig != null && sources.contains(name) && sources.get(name) instanceof StubPropertySource) {
sources.replace(name, new ServletConfigPropertySource(name, servletConfig));
}
}

以上实现中 servletContextservletConfig 参数此时为空,从注释中我们可以看到,该方法是一个幂等方法,也就是该方法可能会被调用多次。这也就解释了,为什么两个关键的参数都为空了。对于接下来的必要属性认证,则是由 StandardEnvironment 的实例完成。我们顺着继承找到最终的方法实现是 AbstractPropertyResolver 类中的 validateRequiredProperties() 方法,以下是它的实现:

1
2
3
4
5
6
7
8
9
10
11
12
@Override
public void validateRequiredProperties() {
MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
for (String key : this.requiredProperties) {
if (this.getProperty(key) == null) {
ex.addMissingRequiredProperty(key);
}
}
if (!ex.getMissingRequiredProperties().isEmpty()) {
throw ex;
}
}

大体逻辑是,通过遍历 this.requiredProperties() 集合中的 key,然后获取每个 key 对应的 value,如果不存在,则将当前的 key 存到 MissingRequiredPropertiesException 对象中,如果该对象不为空,则抛出异常。对于这个 Environment 对象则是在 SpringApplication 的 run() 方法中准备 Environment 阶段创建并设置进来的。默认情况下 this.requiredProperties 为空。方法的最后是添加事件监听器到早期应用监听器里(这里应用监听器的来源包括其他监听器回调添加到容器中的)。

获取容器对象

该容器对象就是底层存储 bean 定义的对象,我们看下实现:

1
2
3
4
5
6
7
8
9
10
/**
* Tell the subclass to refresh the internal bean factory.
* @return the fresh BeanFactory instance
* @see #refreshBeanFactory()
* @see #getBeanFactory()
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}

以上两个方法是抽象方法,我们知道该容器的对外对象为 AnnotationConfigServletWebServerApplicationContext,而该对象又继承了 GenericApplicationContext,这两个抽象方法也是直接继承了它父类的实现。首先我们先看下 refreshBeanFactory()

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Do nothing: We hold a single internal BeanFactory and rely on callers
* to register beans through our public methods (or the BeanFactory's).
* @see #registerBeanDefinition
*/
@Override
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
}

其实该方法什么也没有做,只是添加了一个防止多次刷新的检测,以及为底层的 bean 容器设置序列化 id。而 getBeanFactory() 方法返回的其实就是我们之前提到过的 DefaultListableBeanFactory 实例。好吧,我们继续往下看!

准备 bean 容器

准备 bean 容器阶段做了很多工作,从以下的代码量就能看出:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/**
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
* @param beanFactory the BeanFactory to configure
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 这里将对外容器的类加载器设置给内部容器对象
beanFactory.setBeanClassLoader(getClassLoader());
// 设置 bean 表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

// 为底层容器设置上下文回调处理器
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 忽略相关接口 bean 的自动注入
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

// 注册上下文对象、容器对象、事件发布器、资源载入器
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

// 用于检测是否存在即使织入器
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// 设置一个临时类加载器,用于类型匹配
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}

// 注册默认的环境变量 bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}

内容虽然多,不过没关系,我们一点一点分析。我们先看以下代码:

1
2
3
4
5
6
7
  beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

首先注册了一个 bean 后置处理器,然后配置 bean 容器来忽略以下多个接口类型。为什么要这么做?我们打开 ApplicationContextAwareProcessor 的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
	@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
return bean;
}

AccessControlContext acc = null;

if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}

if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}

return bean;
}

postProcessBeforeInitialization 方法中,我们发现第一个 if 语句中就有刚刚我们忽略接口的类型,也就是对这些接口类型做特殊处理,我们来到 invokeAwareInterfaces() 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}

从以上代码中我们看到,如果是这些接口的实例,则需要手动设置。看到这里是不是还有点疑惑?没关系,我们继续向下看,以下都是 beanFactory.ignoreDependencyInterface() 方法调用,而入参都是刚刚我们看到的接口类型。那就深入去看看该方法的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
	/**
* Ignore the given dependency interface for autowiring.
* <p>This will typically be used by application contexts to register
* dependencies that are resolved in other ways, like BeanFactory through
* BeanFactoryAware or ApplicationContext through ApplicationContextAware.
* <p>By default, only the BeanFactoryAware interface is ignored.
* For further types to ignore, invoke this method for each type.
* @see org.springframework.beans.factory.BeanFactoryAware
* @see org.springframework.context.ApplicationContextAware
*/
public void ignoreDependencyInterface(Class<?> ifc) {
this.ignoredDependencyInterfaces.add(ifc);
}

该方法存在于 AbstractAutowireCapableBeanFactory 类中,该类则是用来处理自动注入的 bean 容器。通过方法的注释我们可以了解到,加入到该集合中的类型将会忽略自动注入。我们看下该集合是怎么使用的:

1
2
3
4
5
protected boolean isExcludedFromDependencyCheck(PropertyDescriptor pd) {
return (AutowireUtils.isExcludedFromDependencyCheck(pd) ||
this.ignoredDependencyTypes.contains(pd.getPropertyType()) ||
AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces));
}

我们把焦点放到 AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces)) 方法上,然后看下它的实现:

1
2
3
4
5
6
7
8
9
10
11
12
public static boolean isSetterDefinedInInterface(PropertyDescriptor pd, Set<Class<?>> interfaces) {
Method setter = pd.getWriteMethod();
if (setter != null) {
Class<?> targetClass = setter.getDeclaringClass();
for (Class<?> ifc : interfaces) {
if (ifc.isAssignableFrom(targetClass) && ClassUtils.hasMethod(ifc, setter)) {
return true;
}
}
}
return false;
}

以上代码的意思就是利用反射获取指定类的 setter 方法,然后判断当前类是否是忽略接口的实例,如果是在判断当前类的 setter 方法是否与接口中的 setter 方法一致,如果是返回 true。什么意思?我们举个例子:

1
2
3
4
5
6
7
8
@Component
public class MyApplicationContextAware implements ApplicationContextAware {

@Autowired
void setApplicationContext(ApplicationContext applicationContext){

}
}

MyApplicationContextAware 实现了 ApplicationContextAware 接口,重写 setApplicationContext 方法。SpringBoot 支持 setter 注入,所以我们在该方法上添加一个 @Autowired 注解。此时就出现问题了,因为 ApplicationContextAware 执行的阶段发生在自动注入阶段之前,所以根本拿不到 ApplicationContext 对象。但是这些实例在 SpringApplication 启动的时候就有了,所以干脆就让这些接口的实例被自动注入忽略,通过手动的方式设置进来。

1
2
3
4
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

为了让 bean 容器也能够注入到我们的程序中,以上需要手动将当前创建好的容器注册到当前 bean 容器里。

1
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

为 bean 容器添加 bean 后置处理器,用于 bean 容器配置期间调用。而 ApplicationListenerDetector 是一个用于检测那些实现了 ApplicationListener 的处理器。

1
2
3
4
5
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}

以上添加两个 bean 处理器,一个是 LoadTimeWeaverAwareProcessor 一个是 ContextTypeMatchClassLoader。前者用于 Spring 提供加载时织入功能,该容器中的任何 bean 都可以实现 LoadTimeWeaverAware 接口,从而接收对加载时织入器实例的引用。后者为一个特殊的类加载器,用于临时匹配类型。

1
2
3
4
5
6
7
8
9
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}

方法的最后则是向容器中注册环境变量 bean。

容器后置处理器

提供了 postProcessBeanFactory(beanFactory) 方法供子类实现,用于修改配置容器信息,而本例中的容器实现并没有覆盖本方法。

调用容器后置处理器

接下来开始调用容器的后置处理器:

1
2
3
4
5
6
7
8
9
10
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}

首先通过 getBeanFactoryPostProcessors() 获取当前容器中的所有容器处理器,然后由 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors 方法负责调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

// 保存处理过的 bean 定义注册处理器的名称,用于去除重复获取到的 bean
Set<String> processedBeans = new HashSet<>();
// 不用多说,DefaultListableBeanFactory 已经实现了 BeanDefinitionRegistry
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// 常规后置处理器(bean 容器后置处理器)
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// 注册处理器(bean 定义注册后置处理器,用于向容器中注册 bean)
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

// 遍历当前容器中存在的容器后置处理器
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 如果当前处理器是 bean 定义注册处理器
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
// 以当前容器作为参数回调处理器方法,向容器中注册 bean 信息
registryProcessor.postProcessBeanDefinitionRegistry(registry);
// 存到注册处理器集合中
registryProcessors.add(registryProcessor);
} else {
// 视为常规的容器处理器
regularPostProcessors.add(postProcessor);
}
}

// 将要回调的处理器
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

// 从当前容器中获取 BeanDefinitionRegistryPostProcessor 类型的 bean 名称,注意这里获取 bean 时,包括了非单例 bean 并且不允许饥饿加载(主要是指 FactoryBean)
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

for (String ppName : postProcessorNames) {
// 筛选出实现优先级接口的 bean
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 添加到待处理集合
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 存到已处理集合中
processedBeans.add(ppName);
}
}
// 开始排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 将具有注册 bean 功能的处理器存放到一起
registryProcessors.addAll(currentRegistryProcessors);
// 回调从容器中获取到的 bean 处理器方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 既然用完了,就可以清空了
currentRegistryProcessors.clear();

// 这次轮到那些实现 Ordered 接口的 bean 注册器了
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 首先判断该 bean 之前是否处理过
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 放到待处理集合中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 添加到已处理集合
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 放到注册器集合中
registryProcessors.addAll(currentRegistryProcessors);
// 开始回调
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 完成之后,清空待处理集合
currentRegistryProcessors.clear();

// 最后,该处理那么没有实现任何排序接口的处理器
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 如果之前没有处理过
if (!processedBeans.contains(ppName)) {
// 存到待处理集合中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// 添加到处理集合中
processedBeans.add(ppName);
// 既然已找到处理器,那就继续遍历,直到全部
reiterate = true;
}
}
// 再排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 只要是注册功能的处理器,就放到一起
registryProcessors.addAll(currentRegistryProcessors);
// 方法回调
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 清空
currentRegistryProcessors.clear();
}

// bean 注册器回调完成之后,该处理 BeanFactory 后置处理器了,registryProcessors 同样也实现了 BeanFactoryPostProcessor 接口
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}

else {
// 如果当前容器不支持注册 bean 的能力,那么就直接回到容器后置处理器进行处理
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}

// 从容器中获取容器后置处理器
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// 优先级后置处理器
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// 具有低优先级的处理器
List<String> orderedPostProcessorNames = new ArrayList<>();
// 默认级别的处理器
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 将不同级别的处理进行分类,如果先前处理过,则直接跳过
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}

// 高优先级排序并回调
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}

// 低优先级排序并回调
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 剩余处理器的回调
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

// 由于后置处理可能已经修改了 bean 的原始元数据,所以需要将缓存下来经过合并的 bean 定义信息清除
beanFactory.clearMetadataCache();
}

代码量很大,不过逻辑很简单就是按优先级调用 bean 注册处理器以及容器后置处理器。