本节讲 Spring bean初始化(3) - ApplicationContext
ApplicationContext和BeanFactory都是用于加载Bean的,但是项目中基本都是使用ApplicationContext,原因是它包括了BeanFactory的所有功能,并且进行了扩展,ApplicationContext初始化过程中会完成所有的单例( no-lazy-init) 的初始化
ApplicationContext ctx = new ClassPathXmlApplicationContext("/spring-code-test.xml");
SysArgDAO bean = (SysArgDAO) ctx.getBean("sysArgDAO");
下面看一下 ClassPathXmlApplicationContext 的具体代码实现
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
// 支持数组方式传入 xml 配置文件
setConfigLocations(configLocations);
if (refresh) {
// 核心逻辑
refresh();
}
}
refresh包括了核心逻辑,在类 AbstractApplicationContext 中
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// 这一步会完成 xml载入,并且将属性放入 beanFactory, 完成了 《Spring bean初始化(1)》
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// 执行 BeanFactoryPostProcessor, 这是 applicationcontext 扩展的功能,保证在bean初始化前做定制
// 比如 PropertyPlaceholderConfigurer,就会处理xml中的变量解析替换(比如 <value>${jdbc.url}</value> ),保证bean初始化之前完成
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 BeanPostProcessor 方法,可以将配置文件中的 BeanPostProcessor 实现直接注册,方法会在getBean的流程中调用,执行 applicationcontext 定制的方法对bean处理
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// 实例化所有 non-lazy-init 单例
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}