SpringBean生命周期

读Spring源码

Posted by Jesse on January 24, 2019

看下ClassPathXmlApplicationContext的构造方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
  private Resource[] configResources;

  // 如果已经有 ApplicationContext 并需要配置成父子关系,那么调用这个构造方法
  public ClassPathXmlApplicationContext(ApplicationContext parent) {
    super(parent);
  }
  ...
  public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
      throws BeansException {

    super(parent);
    // 根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割)
    setConfigLocations(configLocations);
    if (refresh) {
      refresh(); // 核心方法
    }
  }
    ...
}

refresh()方法在AbstractApplicationContext下

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
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			// 为refresh 准备上下文
			prepareRefresh();

			// 这步比较关键,这步完成后,配置文件就会解析成一个个 Bean 定义,注册到 BeanFactory 中,
			// 当然,这里说的 Bean 还没有初始化,只是配置信息都提取出来了,
			// 注册也只是将这些信息都保存到了注册中心(说到底核心是一个 beanName-> beanDefinition 的 map)
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			// 设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				// 这里是提供给子类的扩展点,到这里的时候,所有的 Bean 都加载、注册完成了,但是都还没有初始化
				// 具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// 调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				// 注册 BeanPostProcessor 的实现类,注意看和 BeanFactoryPostProcessor 的区别
				// 此接口两个方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
				// 两个方法分别在 Bean 初始化之前和初始化之后得到执行。注意,到这里 Bean 还没初始化
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				// 初始化当前 ApplicationContext 的 MessageSource,国际化
				initMessageSource();

				// Initialize event multicaster for this context.
				// 初始化当前 ApplicationContext 的事件广播器
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				// 从方法名就可以知道,典型的模板方法(钩子方法),
				// 具体的子类可以在这里初始化一些特殊的 Bean(在初始化 singleton beans 之前)
				onRefresh();

				// Check for listener beans and register them.
				// 注册事件监听器,监听器需要实现 ApplicationListener 接口。
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				// 初始化所有的 singleton beans
				//(lazy-init 的除外)
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				// 最后,广播事件,ApplicationContext 初始化完成
				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.
				// 销毁已经初始化的 singleton 的 Beans,以免有些 bean 会一直占用资源
				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();
			}
		}
	}

Bean生命周期

  • 1、解析xml文件,解析出BeanDefinition
  • 2、Spring容器创建BeanFactoryPostProcessor实例
  • 3、调用BeanFactoryPostProcessor的postProcessBeanFactory方法
  • 4、Spring容器创建BeanPostProcessor实例
  • 5、在需要创建其他Bean实例的时候创建其他Bean
  • 6、调用Bean的构造方法
  • 7、调用Bean的setter方法为Bean属性赋值
  • 8、调用BeanPostProcessor的postProcessBeforeInitialization方法
  • 9、调用InitializingBean的afterPropertiesSet方法
  • 10、调用BeanPostProcessor的postProcessAfterInitialization方法
  • 11、容器销毁的时候调用DisposableBean的destroy方法