IOC容器核心流程
Posted 踩踩踩从踩
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IOC容器核心流程相关的知识,希望对你有一定的参考价值。
前言
Refresh方法
ConfigurableApplicationContext#refresh 中进行定义
经过对该方法的注解解读,发现该方法提供了从加载配置单例bean创建的功能。
这个方法用来加载刷新配置,这些配置可能来自, java 配置、 xml 文件、 properties 文件,关系型数据库,或者其他格式。作为一个启动方法,它应当在初始化失败后销毁已经创建了的单例,防止占着资源不用。也就是说调用这个方法,要么没有所有的单例被创建、要么没有没有单例对象创建。
由AbstractApplicationContext#refresh 实现
public void refresh() throws BeansException, IllegalStateException
synchronized (this.startupShutdownMonitor)
//1 Prepare this context for refreshing.
prepareRefresh();
//2 Tell the subclass to refresh the internal bean factory.
// 为什么要从子类获得刷新后的BeanFactory?
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3 Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try
//4 Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
//5 Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
//6 Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
//7 Initialize message source for this context.
initMessageSource();
//8 Initialize event multicaster for this context.
initApplicationEventMulticaster();
//9 Initialize other special beans in specific context subclasses.
onRefresh();
//10 Check for listener beans and register them.
registerListeners();
//11 Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
//12 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
//13 Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore... resetCommonCaches();
在refresh方法中做的操作
刷新前置的准备 环境属性的添加 然后初始化一些事件监听器列表等等。
整个流程如上图,其中最关键的在于下面的6个方法。
obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory()
refreshBeanFactory();
return getBeanFactory();
对应的实现有AbstractRefreshableApplicationContext、GenericApplicationContext两个类。
AbstractRefreshableApplicationContext
- 自定义Bean工厂属性:Bean定义重写、循环引用等配置
- 创建DefalutListableBeanFactory实例
- 设置ID
- 等待子类实现的,向bean工厂注册Bean定义
- 持有bean工厂实例,以便在getBeanFactory方法中返回出去
GenericApplicationContext
GenericApplicationContext中的刷新方法,只能被调用一次,被Atomic的refreshed状态控制着。
刷新的方法也很简单,只是设置了一个ID。
prepareBeanFacotry
- 给bean工作准备ClassLoader、SPL表达是解析器、属性编辑注册器等
- 向BeanFactory注册ApplicationContextAwareProcessor
- 依赖需要使用的bean,IOC容器自己的多角色身份 @Autowried方式获得下列类型bean
-
注入ApplicationListeners接口实现的发现处理器,同时带有销毁、bean定义混合的实现。
-
操作系统环境变量:JAVA_HOME等
BeanPostProcessor的注入
invokeBeanFactoryPostProcessors
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法解读
BeanFactoryPostProcessor与容器
BeanFactoryPostProcessors的调用处理
registerBeanPostProcessors
PostProcessorRegistrationDelegate.registerBeanPostProcessors
initMessageSource
此时BenPostProcessor都已经注册完成,下一步准备资源国际化的事宜。
registerListeners
国际化资源准备完毕,接下来,检查事件监听器,并注册到事件传播器上。在不生成Bean对象的情况下添加ApplicationListener bean作为监听器
这两种去获取 beanfactory的方式。 效果都是一样的。
finishBeanFactoryInitialization
容器的关闭
以上是关于IOC容器核心流程的主要内容,如果未能解决你的问题,请参考以下文章
深入浅出Spring原理及实战「原理分析专题」不看源码就带你剖析IOC容器核心流程以及运作原理