概述
spring
版本6.0.12
,整体概括
相关连接
阅读之前,可以浏览一下
spring 对象初始化
以一个最简单对象初始化,没有依赖其它
bean
,就是最基础的pojo
由spring
初始化的过程
除去上图四个步骤,是不是和平时使用反射生成一个对象的步骤,很相似
BeanDefinition
来源(xml文件与注解)- 创建对象的方式(构造器或工厂方法为主流),反射也分java的Proxy或cglib
- 上图的四个步骤是spring里经典的一些扩展点
spring关键代码
spring
关键逻辑
public void refresh() throws BeansException, IllegalStateException {
// 加锁,防止多线程重复启动
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
// 一.准备刷新
// 1.设置容器的启动时间
// 2.设置活跃状态为true
// 3.设置关闭状态为false
// 4.获取Environment对象,并加载当前系统的属性值到Environment对象中
// 5.准备监听器和时间的集合对象,默认为空的集合
prepareRefresh();
// 二. 初始化 新的BeanFactory
// 1.如果存在旧 BeanFactory,则销毁
// 2.创建新的 BeanFactory (DefaultListableBeanFactory)
// 3.解析xml/加载bean定义,注册bean定义到beanFactory(不初始化)
// 4.返回新的 BeanFactory (DefaultListableBeanFactory)
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 三.bean工厂前置操作 为BeanFactory配置容器特性
// 例如:类加载器,表达式解析器,注册默认环境 bean,后置处理器 BeanPostProcessor
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// 四. bean工厂后置操作 此处为空方法,如果子类需要,需自己实现
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 五.调用bean工厂后置处理器,执行已注册的beanFactoryPostProcessor的实现类,大这里完成了类的扫描,解析
// 目标:
// 调用顺序一:先bean定义,注册后置处理器
// 调用顺序二:后bean工厂后置处理器
// 调用BeanFactoryPostProcessor各个实现类的postProcessBeanFactory(factory)回调方法
// Invoke factory processors registered as beans in the context.
// 该方法会 实例化 和 调用 所有 BeanFactoryPostProcessor(包括其子类 BeanDefinitionRegistryPostProcessor)
// BeanDefinitionRegistryPostProcessor 继承自 BeanFactoryPostProcessor,
// 比 BeanFactoryPostProcessor 具有更高的优先级,
// 主要用来在常规的 BeanFactoryPostProcessor 检测开始之前注册其他 bean 定义。
// 特别是,可以通过 BeanDefinitionRegistryPostProcessor 来注册一些常规的 BeanFactoryPostProcessor,
// 因为此时所有常规的 BeanFactoryPostProcessor 都还没开始被处理。
invokeBeanFactoryPostProcessors(beanFactory);
// 六.注册bean后置处理器 只是注册,还不会调用
// 逻辑:找出所有实现BeanPostProcessor接口的类,分类,排序,注册
// ----------------------------------
// 方法作用:会注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类注册到 BeanFactory 中。
// BeanPostProcessor 接口是 Spring 初始化 bean 时对外暴露的扩展点
// 在所有 bean 实例化时,执行初始化方法前会调用所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法,
// 在执行初始化方法后会调用所有 BeanPostProcessor 的 postProcessAfterInitialization 方法。
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 七.初始化消息源 国际化问题i18n
// Initialize message source for this context.
initMessageSource();
// 八.初始化事件广播器 初始化自定义的事件监听多路广播器
// 如果需要发布事件,就调它的multicastEvent方法
// 将事件广播给listeners,其实就是起一个线程来处理,将Event扔给listener处理
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// 九.刷新:拓展方法 这是个protected空方法,交给具体的子类实现
// 可以在这里初始化一些特殊的bean
// Initialize other special beans in specific context subclasses.
onRefresh();
// 十.注册监听器,监听器需要实现 ApplicationListener 接口
// 也就是扫描这些实现了接口的类,给他放进广播的列表中
// 其实是个观察者模式,广播器接到事件的调用时,去循环listeners列表
// 挨个调它们的onApplicationEvent方法,将event扔给它们
// Check for listener beans and register them.
registerListeners();
// 十一.实例化所有剩余的(非惰性初始化)单例
// 1.初始化所有的 singleton beans, 反射生成对象/填充
// 2.调用bean的前置处理器和后置处理器
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// 十二.结束refresh操作
// 发布事件与清除上下文环境
// Last step: publish corresponding event.
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();
contextRefresh.end();
}
}
}
结束
在后面的文章中,将对这些关键方法进行详细的说明