Spring-IOC原理(四)

前言

在上一篇博文《Spring-IOC原理(三)》中分析了AnnotationConfigApplicationContext构造函数中的前两个步骤,接下来我们分析最后一步,这最后一步也是整个过程的核心方法,几乎所有的操作都在这个最后的方法中完成。而且最后这个方法中调用链比较深,所以这次我们先大致捋一下最后方法中的所有大致流程,然后在逐个方法去解析其中的过程。下面我们就开始分析最后一个重要的方法refresh()。进入到refresh()方法中。

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
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
/**
* 刷新预处理,这里主要是保存了容器的启动时间、启动标志等信息;和主流程的关系不大
*/
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
/**
* 这里最终获取了ConfigurableListableBeanFactory,和主流程的关系也不大
* DefaultListableBeanFactory实现了ConfigurableListableBeanFactory
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
/** 准备这个上下文要数用的bean工厂 ,这里会设置beanFactory忽略的依赖接口(一些Aware接口),注册一些bean工厂依赖的bean(BeanFactory、ApplicationContext
* ApplicationEventPublisher、ResourceLoader),以及一些默认的bean。
* 添加了两个后置处理器:ApplicationContextAwareProcessor、ApplicationListenerDetector
* 设置了bean表达式解析器等
*/
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
/** 注册上下文子类的后置处理器 */
postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.
/** 实例化并调用所有已经注册的BeanFactoryPostProcessor,会解析@Import@Component等注解 */
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
/** 注册BeanPostProcessors后置处理器 */
registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.
// 初始化国际化资源处理器。不是主线程代码
initMessageSource();

// Initialize event multicaster for this context.
/** 初始化事件多播器,容器是使用自定义的广播器还是默认的时间广播器都是在这个方法中进行处理的 */
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
/** 初始化特定容器中的指定bean,这个方法时空方法,用来扩展用。
* 该方法是模板方法,容器刷新的时候可以自定义逻辑,不同的spring容器有不同的实现
*/
onRefresh();

// Check for listener beans and register them.
/** 注册事件监听器 */
registerListeners();

// Instantiate all remaining (non-lazy-init) singletons.
/** 实例化剩余的单例Bean(非懒加载)
* 比如invokeBeanFactoryPostProcessors(beanFactory)方法中根据各种注解解析出来的类,在这个时候才会被初始化
* 实例化的过程各种BeanPostProcessor开始起作用
*/
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
/** 最后发布相应的事件
* 清除上下文资源缓存
* 初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)
* 发布ContextRefreshedEvent事件告诉对应的ApplicationListener进行响应操作
*/
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}

// Destroy already created singletons to avoid dangling resources.
destroyBeans();

// Reset 'active' flag.
cancelRefresh(ex);

// Propagate exception to caller.
throw ex;
}

finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}

一、prepareRefresh()

首先,会进行初始化前的准备工作,通过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
39
40
41
42
43
44
45
46
47
48
49
50
51
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());
}
}

// Initialize any placeholder property sources in the context environment.
/** 在上下文环境中初始化任何占位符属性源。
* 如果一个类重写了initPropertySources()方法,比如设置了一个环境变量testProperty,
* 在容器启动的时候,会去环境变量中寻找testProperty,如果没有找到这个属性就会抛出异常
*/
initPropertySources();

// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
/** 校验环境依赖的所有环境变量或者属性是否存在,是否可以解析,
* 这一步和上一步initPropertySources()相互配合使用,在initPropertySources()中设置了环境变量,
* 在这一步检测环境变量在配置文件中是否已经配置了。
* 例如:在initPropertySources()中配置了testProperty属性,那么在validateRequiredProperties()中
* 会检测环境变量是否真正有这个testProperty属性,是否可以解析这个属性,如果不存在这个testProperty属性,
* 那么会抛出MissingRequiredPropertiesException异常
*/
getEnvironment().validateRequiredProperties();

// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}

// Allow for the collection of early ApplicationEvents,to be published once the multicaster is available...
// to be published once the multicaster is available...
/** 创建早期多播器,一旦多播器可用就可以发送事件
* 所谓早期多播器就是:我们的事件监听器还没有注册到多播器上的时候,都是早期事件,早期事件不许要手动publishEvent发布,在
* RegisterListener中会自动发布
*/
this.earlyApplicationEvents = new LinkedHashSet<>();
}

在这个方法中主要进行了三个操作:

  1. 通过initPropertySources()初始化了属性源占位符,这个方法默认是空实现,如果一个类重写了initPropertySources()方法,比如设置了一个环境变量test,那么在容器启动的时候,spring会去环境变量中寻找test属性,如果没有找到这个属性就会抛出异常。

  2. 通过getEnvironment().validateRequiredProperties()检测环境依赖的所有环境变量或者属性是否存在,是否可以解析。这一步操作和上一步操作initPropertySources()是相互配合使用的,在initPropertySources()中设置了环境变量,在这一步会检测环境变量在配置文件中是否已经配置。

    例如:在initPropertySources()中配置了test属性,那么会在validateRequiredProperties()中检测环境变量是否真正有这个test属性,是否可以解析这个属性,如果不存在test属性,就会抛出MissingRequiredPropertiesException异常

​ 这里还有一个小的知识点,就是在spring中我们可以怎么获取配置文件application.yml中配置的属性值。常用的有两种方式:①是 通过使用@Value,例如:在相应的字段上标注@Value("${server.port}")就可以读取到服务的端口;②通过@ConfigurationProperties注解,在需要读取的实体类上标注该注解,例如:

1
2
3
4
5
6
7
8
9
10
@Component
@ConfigurationProperties(prefix = "student")
@Data
/**
* 接收配置信息的实体类
*/
public class Student {
private String name;
private Integer age;
}

application.yml中的配置如下

1
2
3
student:
age: 18
name: mysgk

需要注意的是在使用@ConfigurationProperties注解时,需要配置一一个prefix前缀参数。

③最后一个是通过注入Environment来获取我们想要的属性,Environment就是在getEnvironment()方法中初始化创建出来的,我们进如到getEnvironment()方法中

1
2
3
4
5
6
7
@Override
public ConfigurableEnvironment getEnvironment() {
if (this.environment == null) {
this.environment = createEnvironment();
}
return this.environment;
}

通过调用方法createEnvironment()来完成创建

1
2
3
protected ConfigurableEnvironment createEnvironment() {
return new StandardEnvironment();
}

那么StandardEnvironment是个什么东东,我们看一看它的类继承关系

StandardEnvironment类继承关系

​ 当然这里也只是初始化了Evironment,还没有进行配置属性装载,具体装载会在prepareBeanFactory()中完成

  1. this.earlyApplicationEvents 创建了早期多播器,一旦多播器被创建,就可以发送事件了。什么是多播器呢,所谓早期多播器就是:我们的事件监听器还没有注册到多播器上的时候,都是早期事件,早期事件是不需要手动publishEvent发布,在RegisterListener中自动完成

二、obtainFreshBeanFactory()

1
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

这个方法和主流程的关系也不大,这里只是获取了我们在之前创建好的DefaultListableBeanFactory,那这里为什么是ConfigurableListableBeanFactory类型呢,因为我们的DefaultListableBeanFactory是实现了ConfigurableListableBeanFactory的。

再回顾一下DefaultListableBeanFactory是在哪里创建的。之前我们说过,在执行AnnotationConfigApplicationContext构造方法之前会首先执行其父类的构造方法,

GenericApplicationContext

从上图可以看出,在父类构造方法中实例化了beanFactory,而beanFactory的类型是DefaultListableBeanFactory

三、prepareBeanFactory(beanFactory)

在这个方法中主要是准备上下文要用的bean工厂,这里会设置beanFactory忽略的依赖接口(例如一下Aware接口),注册一些bean工厂依赖的bean(BeanFactoryApplicationContextApplicationEventPublisherResourceLoader等),以及一些默认的bean。同时也添加了两个后置处理器:ApplicationContextAwareProcessorApplicationListenerDetector,设置了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
50
51
52
53
54
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
/** 告诉内部bean工厂使用上下文的类加载器等 */
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

// Configure the bean factory with context callbacks.
/** 添加一个后置处理器:ApplicationContextAwareProcessor,这个后置处理器实现了BeanPostProcessor接口 */
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);

// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
/** 为beanFactory注册解析依赖的bean */
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.
/** 为bean工厂注册一个早期的后置处理器,这个后置处理器是一个监听器(ApplicationListenerDetector) */
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

// Detect a LoadTimeWeaver and prepare for weaving, if found.
/** 如果存在LoadTimeWeaver,就将其注册为LoadTimeWeaverAwareProcessor后置处理器 */
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()));
}

// Register default environment beans.
/** 注册默认环境的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. 设置bean表达式解析器
  3. 添加属性编辑器的支持
  4. 添加一个后置处理器:ApplicationContextAwareProcessor,此后置处理器实现了BeanPostProcessor接口
  5. 设置了一些忽略自动装配的接口
  6. 设置了一些允许自动装配的接口,并且进行了赋值操作
  7. 在容器中还没有XXX的bean的时候,为我们注册了beanName为XXX的singleton bean

四、postProcessBeanFactory(beanFactory)

这里的这个方法是空方法,spring没有去实现,主要是提供给要实现BeanPostProcessor的第三方框架使用的,如果要整合spring,那么就会要实现postProcessBeanFactory()方法。主要是在spring的BeanFactory准备工作完成之后做一些额外的定制化处理,一般会结合BeanPostProcessor接口实现类来使用,在该方法中还要设置一些忽略的自动装配类。例如AbstractRefreshableWebApplicationContext类中就实现了这个方法。

1
2
3
4
5
6
7
8
9
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}

在上述AbstractRefreshableWebApplicationContext类中的postProcessBeanFactory()方法中添加了一个ServletContextAwareProcessor后置处理器,那么在这个后置处理器中的postProcessBeforeInitialization()方法肯定也会有实现。如下

1
2
3
4
5
6
7
8
9
10
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (getServletContext() != null && bean instanceof ServletContextAware) {
((ServletContextAware) bean).setServletContext(getServletContext());
}
if (getServletConfig() != null && bean instanceof ServletConfigAware) {
((ServletConfigAware) bean).setServletConfig(getServletConfig());
}
return bean;
}

五、invokeBeanFactoryPostProcessors(beanFactory)

这里spring会实例化并调用所有已经注册的BeanFactoryPostProcessor,同时这里也会解析@Import@Component等注解。

1
2
3
4
5
6
7
8
9
10
11
12
13
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
/**
* 1.getBeanFactoryPostProcessors(): 拿到当前应用上下文beanFactoryPostProcessors变量中的值
* 2.invokeBeanFactoryPostProcessors: 实例化并调用所有已注册的BeanFactoryPostProcessor
*/
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()拿到当前应用上下文beanFactoryPostProcessors变量中的值,然后调用invokeBeanFactoryPostProcessors()实例化并调用所有已经注册的BeanFactoryPostProcessor。具体PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法中的执行逻辑在之后的博文中详细讲解,因为这个方法中调用链比较深。这里只是简单了解大概流程。

六、registerBeanPostProcessors(beanFactory)

这里会注册BeanPostProcessors后置处理器

1
2
3
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

继续进入到PostProcessorRegistrationDelegate.registerBeanPostProcessors()方法中

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
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
/** 注册一个BeanPostProcessorChecker 当bean在BeanPostProcessor被实例化创建时期间,
* 即当有一个bean不符合所有BeanPostProcessors处理的条件时,会记录消息日志*/
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
/** 将实现PriorityOrdered接口,Ordered接口和其他接口的BeanPostProcessors分离开来 */
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}

// First, register the BeanPostProcessors that implement PriorityOrdered.
/** 首先,注册实现了PriorityOrdered接口的BeanProcessors */
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

// Next, register the BeanPostProcessors that implement Ordered.
/** 接下来,注册实现Ordered接口的BeanPostProcessors */
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);

// Now, register all regular BeanPostProcessors.
/** 注册剩余其他的BeanPostProcessors */
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

// Finally, re-register all internal BeanPostProcessors.
/** 最后,再注册所有的内部BeanPostProcessors */
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);

// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
/** 重新注册后处理器以将内部 bean 注册为 ApplicationListeners,将其移动到处理器链的末尾(用于获取代理等) */
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
  1. 先注册了一个BeanPostProcessorChecker后置处理器,该后置处理器的主要作用是,当bean在BeanPostProcessor被实例化创建时,会记录消息日志,

  2. 将实现了PriorityOrdered接口、Ordered接口和其他接口的BeanPostProcessors分离出来,用priorityOrderedPostProcessors集合来保存实现了PriorityOrdered接口的bean,将实现了Ordered接口的类名字保存到orderedPostProcessorNames缓存中,bean类型为MergedBeanDefinitionPostProcessor的bean保存到internalPostProcessors缓存中,除此之外的其他接口,将接口名保存到nonOrderedPostProcessorNames缓存中。

  3. 对所有实现了PriorityOrdered接口进行排序,将priorityOrderedPostProcessors缓存进行排序

    1
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);

    然后将排好序的priorityOrderedPostProcessors缓存中的所有BeanPostProcessor进行注册

    1
    2
    3
    4
    5
    6
    7
    8
    private static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
    /** 遍历postProcessors */
    for (BeanPostProcessor postProcessor : postProcessors) {
    /** 将postProcessor添加到BeanFactory的beanPostProcessors缓存中 */
    beanFactory.addBeanPostProcessor(postProcessor);
    }
    }
  4. 对实现Ordered接口的所有类即orderedPostProcessors缓存进行排序,并进行注册,过程同第3步。

  5. 最后再对剩余的其他BeanPostProcessorinternalPostProcessors缓存中的bean进行排序和注册;过程同第3步。

  6. 注册了一个后置处理器ApplicationListenerDetector

七、initMessageSource()

这个方法中主要是初始化了一些国际化资源,和主流程相关不大,暂且不对initMessageSource()方法中的代码展开阅读,知道其大致功能就好。

八、initApplicationEventMulticaster()

初始化了事件多播器,容器是使用自定义的广播器还是默认的事件广播器都是在这个方法中进行处理的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
/**
* 用户可以在配置文件中为容器定义一个自定义的事件广播器,只要实现了ApplicationEventMulticaster接口就可以,
* Spring会通过反射机制将其注册成容器的事件广播器,如果灭有找到匹配的外部事件广播器,Spring自动使用默认的
* SimpleApplicationEventMulticaster作为事件广播器
*/
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}

监听器大致执行流程如下

监听器流程

九、onRefresh()

这个方法是一个空方法,没有任何实现,只是spring用来做扩展使用的,当容器刷新的时候可以重写这个方法,自定义业务逻辑代码;因为不同的spring容器可能会有不同的实现。

十、registerListeners()

这个方法中注册了事件监听器,并且通过调用ApplicationEventMulticaster中的multicastEvent发布了早期事件

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
protected void registerListeners() {
// Register statically specified listeners first.
/** 首先,注册指定的静态监听器 */
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}

// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
/** 不在这里初始化FactoryBeans,需要让所有的常规bean处于未初始化的状态,让后置处理器去初始化他们 */
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}

// Publish early application events now that we finally have a multicaster...
/** 使用注册好的多播器发布早期应用事件 */
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
/** 调用ApplicationEventMulticaster中的multicastEvent发布事件 */
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}

十一、finishBeanFactoryInitialization(beanFactory)

实例化所有剩余的单例Bean(非懒加载的bean),比如:在invokeBeanFactoryPostProcessors(beanFactory)方法中根据各种注解解析出来的类(实现了BeanFactoryPostProcessor接口的bean、实现了BeanPostProcessor接口的bean),在这个时候才会被初始化,在实例的过程中各种BeanPostProcessor才开始起作用。**BeanPostProcessor的触发也是在这个方法中**

大致看一下finishBeanFactoryInitialization()中的代码,具体逻辑在另外博文中具体详谈,这里调用链比较深,先了解一下大概即可。

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
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
/** 初始化上下文属性转换器 */
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}

// Register a default embedded value resolver if no BeanFactoryPostProcessor
// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
/** 如果在此之前没有注册过BeanFactoryPostProcessor后置处理器(像PropertySourcesPlaceholderConfigurer bean),
* 则注册一个默认的嵌入值解析器,主要来解析注解属性值 */
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}

// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
/** 初始化 LoadTimeWeaverAware bean,目的是为了后面注册他们的转换器 */
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}

// Stop using the temporary ClassLoader for type matching.
/** 停止使用临时的 ClassLoader来进行类型匹配 */
beanFactory.setTempClassLoader(null);

// Allow for caching all bean definition metadata, not expecting further changes.
/** 冻结所有的bean定义, 说明注册的bean定义将不能被修改或任何进一步的处理 */
beanFactory.freezeConfiguration();

// Instantiate all remaining (non-lazy-init) singletons.
/** 实例化剩余的单例Bean */
beanFactory.preInstantiateSingletons();
}

finishBeanFactoryInitialization()方法中主要做了一下几步操作:

  1. 初始化上下文属性转换器
  2. 注册属性解析器
  3. 初始化Aware的bean
  4. 冻结所有的bean定义,此时,注册的所有bean定义将不能被修改或任何的进一步操作
  5. 实例化剩余的单例Bean。这一步比较重要,会另外在写 博文单独解析这个方法

十二、finishRefresh()

最后发布相应的事件,在这方法中也会清除上下文资源缓存,初始化上下文周期处理器,并刷新。最后会发布ContextRefreshedEvent事件告诉对应的ApplicationListener进行相应的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
/** 清除上下文资源缓存(如扫描中的ASM元数据) */
clearResourceCaches();

// Initialize lifecycle processor for this context.
/** 为上下文初始化晟敏周期处理器 */
initLifecycleProcessor();

// Propagate refresh to lifecycle processor first.
/** 首先,将刷新完毕的事件传到生命周期处理器(触发isAutoStartup)方法返回true的SmartLifecycle的start()方法 */
getLifecycleProcessor().onRefresh();

// Publish the final event.
/** 推送上下刷新完毕事件到相应的监听器 */
publishEvent(new ContextRefreshedEvent(this));

// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!

请我喝杯咖啡吧~

支付宝
微信