看了网上很多文章的解释,发现解释的很乱,结合自己的理解加上看了书籍《spring技术内幕》的内容,发现spring?bean的周期贯穿了初始化和依赖注入。
初始化
对容器的启动来说,refresh() 是一个很重要的方法。该方法在 AbstractApplicationContext 类中,详细地描述了整个 ApplicationContext 的初始化过程。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
// 在子类中启动 refreshBeanFactory()
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// 设置 BeanFactory 的后置处理
postProcessBeanFactory(beanFactory);
// 调用 BeanFactory 的后处理器(在 bean 定义中向容器注册的)
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 bean 的后处理器,在 bean 创建过程中调用
registerBeanPostProcessors(beanFactory);
// 对上下文中的消息源进行初始化
initMessageSource();
// 初始化上下文中的事件机制
initApplicationEventMulticaster();
// 初始化其它特殊 bean
onRefresh();
// 检查监听 bean 并且将这些 bean 向容器注册
registerListeners();
// 实例化所有 non-lazy-init 单例
finishBeanFactoryInitialization(beanFactory);
// 发布容器事件
finishRefresh();
} catch (BeansException ex) {
// 在异常处理中,为防止 bean 资源占用,销毁已经生成的单例 bean
destroyBeans();
// 重置 active 标志
cancelRefresh(ex);
throw ex;
}
}
}
BeanDefinition 的 Resource 定位
FileSystemXmlApplicationContext 从 文件系统 载入 Resource
ClassPathXmlApplicationContext 从 classpath 载入 Resource
XmlWebApplicationContext 从 web 容器 载入 Resource
BeanDefinition 的载入和解析 BeanDefinition 在 ioc 容器中的注册
载入和解析过程完成后,定义的 BeanDefinition 信息已经在 ioc 容器内建立起了自己的数据结构以及相应的数据表示,此时这些数据还不能供 ioc 容器直接使用,需要在 ioc 容器中对这些 BeanDefinition 数据进行注册。
在 DefaultListableBeanFactory 中,通过一个 HashMap 持有载入的 BeanDefinition 。
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
依赖注入
getBean() 执行到 AbstractAutowireCapableBeanFactory 的 doCreateBean() 方法执行以下几个方法
createBeanInstance() 创建 BeanWrapper 实例
populateBean() 方法对 BeanWrapper 进行属性赋值
initializeBean() 方法中执行4个方法
看到?applyBeanPostProcessorsBeforeInitialization()、invokeInitMethods()、applyBeanPostProcessorsAfterInitialization() 三个方法的顺序关系,想起了 aop 的前置通知、后置通知。
registerDisposableBeanIfNecessary() 调用 DisposableBean 接口的实现类的 destroy() 进行销毁
|