IOC 加载过程 从 new ClassPathXmlApplicationContext开始
ApplicationContext context = new
ClassPathXmlApplicationContext("classpath:application.xml");
ClassPathXmlApplicationContext类构造方法
public ClassPathXmlApplicationContext(String[] configLocations,
boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
super(parent);
this.setConfigLocations(configLocations);
if (refresh) {
// 执行刷新操作
this.refresh();
}
}
核心类和接口
ApplicationContext接口 其实就是一个BeanFactory
作用: 加载配置文件中定义的 bean,并进行管理。
继承了ListableBeanFactory,这个ListableBeanFactory接口可以获取多个bean。
继承了HierarchicalBeanFactory接口,这个接口可以在应用这起多个BeanFactory,然后将多个BeanFactory设置父子关系。
getAutowireCapableBeanFactory() : 用来自动装配Bean
BeanDefinitionReader
配置文件解析器,如将配置文件中的 bean 信息解析成对应的 BeanDefinition 对象。
xml 文件解析使用是就是BeanDefinitionReader 实现类 XmlBeanDefinitionReader。
BeanFactoryPostProcessor
可以修改 Spring 上下文中 BeanDefinition 信息。
BeanFactory
是所有 Bean 容器的根接口,定义了 spring 容器基本方法。如使用 getBean(beanName,Class) 获取对象。
refresh() 详解
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//1:准备刷新上下文环境。
prepareRefresh();
//2:刷新并获取刷新后的 BeanFactory,将配置文件解析为BeanDefinition对象。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3:对 Bean 工厂进行填充属性。
prepareBeanFactory(beanFactory);
try {
//4:beanFactory的后置处理器,空方法,具体由子类实现。
// 使用设计模式中的模板方法,是一个钩子函数。
postProcessBeanFactory(beanFactory);
//5:实例化并调用所有注册的beanFactory后置处理器。
invokeBeanFactoryPostProcessors(beanFactory);
//6:加载 BeanPostProcessors。
registerBeanPostProcessors(beanFactory);
//7:国际化处理,为上下文实例化并注册一个MessageSource。
initMessageSource();
//8:初始化并注册一个事件广播器用来发布事件。
initApplicationEventMulticaster();
//9:空方法,由子类实现,使用设计模式中的模板方法,是一个钩子函数。
onRefresh();
//10:注册监听器,在所有注册的bean中查找Listener bean,注册到消息广播器中,即向监听器发布事件。
registerListeners();
//11:初始化所有的非懒加载的单实例bean(bean的生命周期实例化 属性注入 初始化 完成)
finishBeanFactoryInitialization(beanFactory);
//12:最后刷新容器 发布刷新事件。
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()
准备刷新上下文环境。
obtainFreshBeanFactory()(重要)
刷新并获取刷新后的 BeanFactory,将配置文件解析为BeanDefinition对象。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//刷新bean工厂()
refreshBeanFactory();
//返回之前容器准备工作的时候创建的的bean工厂也就是DefaultListableBeanFactory(很重要)
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
protected final void refreshBeanFactory() throws IllegalStateException {
//由于BeanFactory只能刷新一次,多线程情况下可能导致线程安全问题,所有使用cas原子操作来保证
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
//指定Bean工厂的序列化Id
this.beanFactory.setSerializationId(getId());
}
prepareBeanFactory()
对 Bean 工厂进行填充属性。
postProcessBeanFactory()
beanFactory的后置处理器,空方法,具体由子类实现。使用设计模式中的模板方法,是一个钩子函数。
invokeBeanFactoryPostProcessors()
实例化并调用所有注册的beanFactory后置处理器。
registerBeanPostProcessors()
加载 BeanPostProcessors。
initMessageSource()
国际化处理,为上下文实例化并注册一个MessageSource。
initApplicationEventMulticaster()
初始化并注册一个事件广播器用来发布事件。
onRefresh()
空方法,由子类实现,使用设计模式中的模板方法,是一个钩子函数。
registerListeners()
注册监听器,在所有注册的bean中查找Listener bean,注册到消息广播器中,即向监听器发布事件。
finishBeanFactoryInitialization()(重要)
初始化所有的非懒加载的单实例bean(bean的生命周期实例化 属性注入 初始化 完成)。
bean实例化 属性注入 初始化
关键方法
AbstractAutowireCapableBeanFactory类的doCreateBean方法
// 其中
createBeanInstance(beanName, mbd, args); // 实例化
populateBean(beanName, mbd, instanceWrapper); // 属性注入
initializeBean(beanName, exposedObject, mbd) // 初始化
finishRefresh()
最后刷新容器发布刷新事件。
待续…
IOC容器步骤详解
面试详解