1、初始化流程
①:如果我想生成 bean 对象,那么就需要一个 beanFactory 工厂(DefaultListableBeanFactory
);
②:如果我想对加了特定注解(如 @Service
、@Repository
)的类进行读取转化成 BeanDefinition
对象(BeanDefinition
是 Spring 中极其重要的一个概念,它存储了 bean 对象的所有特征信息,如是否单例,是否懒加载,factoryBeanName 等),那么就需要一个注解配置读取器(AnnotatedBeanDefinitionReader
);
③:如果我想对用户指定的包目录进行扫描查找 bean 对象,那么还需要一个路径扫描器(ClassPathBeanDefinitionScanner
)。
2、刷新流程
看完流程图,我们也先思考一下:在 3.1 中我们知道了如何去初始化一个 IOC 容器,那么接下来就是让这个 IOC 容器真正起作用的时候了:即先扫描出要放入容器的 bean,将其包装成 BeanDefinition
对象,然后通过反射创建 bean,并完成赋值操作,这个就是 IOC 容器最简单的功能了。但是看完上图,明显 Spring 的初始化过程比这个多的多,下面我们就详细分析一下这样设计的意图:
如果用户想在扫描完 bean 之后做一些自定义的操作:假设容器中包含了 a 和 b,那么就动态向容器中注入 c,不满足就注入 d,这种骚操作 Spring 也是支持的,得益于它提供的 BeanFactoryPostProcessor
后置处理器,对应的是上图中的 invokeBeanFactoryPostProcessors
操作。
如果用户还想在 bean 的初始化前后做一些操作呢?比如生成代理对象,修改对象属性等,Spring 为我们提供了 BeanPostProcessor
后置处理器,实际上 Spring 容器中的大多数功能都是通过 Bean 后置处理器完成的,Spring 也是给我们提供了添加入口,对应的是上图中的 registerBeanPostProcessors
操作。
整个容器创建过程中,如果用户想监听容器启动、刷新等事件,根据这些事件做一些自定义的操作呢?Spring 也早已为我们考虑到了,提供了添加监听器接口和容器事件通知接口,对应的是上图中的 registerListeners
操作。
此时再看上图,是不是就觉得简单很多呢,下面就一些重要代码进行分析。
②、核心代码剖析
org.springframework.context.support.AbstractApplicationContext#refresh
这个方法是对上图中的具体代码实现,可划分为12个步骤,其中比较重要的步骤下面会有详细说明。
在这里,我们需要记住:Spring 中的每一个容器都会调用 refresh 方法进行刷新,无论是 Spring 的父子容器,还是 Spring Cloud Feign 中的 feign 隔离容器,每一个容器都会调用这个方法完成初始化。
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 |
public void refresh() throws BeansException, IllegalStateException {
synchronized ( this .startupShutdownMonitor) {
// Prepare this context for refreshing.
// 1. 刷新前的预处理
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 2. 获取 beanFactory,即前面创建的【DefaultListableBeanFactory】
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 3. 预处理 beanFactory,向容器中添加一些组件
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 4. 子类通过重写这个方法可以在 BeanFactory 创建并与准备完成以后做进一步的设置
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 5. 执行 BeanFactoryPostProcessor 方法,beanFactory 后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 6. 注册 BeanPostProcessors,bean 后置处理器
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 7. 初始化 MessageSource 组件(做国际化功能;消息绑定,消息解析)
initMessageSource();
// Initialize event multicaster for this context.
// 8. 初始化事件派发器,在注册监听器时会用到
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 9. 留给子容器(子类),子类重写这个方法,在容器刷新的时候可以自定义逻辑,web 场景下会使用
onRefresh();
// Check for listener beans and register them.
// 10. 注册监听器,派发之前步骤产生的一些事件(可能没有)
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 11. 初始化所有的非单实例 bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 12. 发布容器刷新完成事件
finishRefresh();
}
...
}
|