博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
04.Spring Ioc 容器 - 刷新
阅读量:5084 次
发布时间:2019-06-13

本文共 4583 字,大约阅读时间需要 15 分钟。

基本概念

Spring Ioc 容器被创建之后,接下来就是它的初始化过程了。该过程包含了配置、刷新两个步骤 

刷新由 Spring 容器自己实现,具体发生在 ConfigurableApplicationContext 的 refresh 方法中。

首先来看该接口的继承关系:

Alt text

由于这里 Spring 的配置文件采用 xml 形式,所以 Ioc 容器的类型默认为 XmlWebApplicationContext。接下来就以该类的 refresh 方法为入口,探究下 Ioc 容器的刷新过程。


原理分析

该类的 refresh 方法继承自己父类 AbstractApplicationContext,观察代码可以发现该方法包含了众多方法,这里只探究下 1、2 过程。

private final Object startupShutdownMonitor = new Object();public void refresh() throws BeansException, IllegalStateException { // 加锁 synchronized (this.startupShutdownMonitor) { // 1.准备刷新 prepareRefresh(); // 2.创建内部容器,该容器负责 Bean 的创建与管理 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); prepareBeanFactory(beanFactory); try { postProcessBeanFactory(beanFactory); invokeBeanFactoryPostProcessors(beanFactory); registerBeanPostProcessors(beanFactory); initMessageSource(); initApplicationEventMulticaster(); onRefresh(); registerListeners(); finishBeanFactoryInitialization(beanFactory); finishRefresh(); } catch (BeansException ex) { // 省略代码... destroyBeans(); cancelRefresh(ex); throw ex; } finally { resetCommonCaches(); } } }

准备刷新

初始化准备,即为 Ioc 容器的初始化过程做准备,该过程与 Spring 的 Environment 有关,这里暂不探究。

// 容器早期发布事件集private Set
earlyApplicationEvents;protected void prepareRefresh() { // 省略部分代码... // 1.激活容器 this.active.set(true); // 2.初始化 Environment 的 propertySources 属性 initPropertySources(); // 3.校验 Environment 的 requiredProperties 是否都存在 getEnvironment().validateRequiredProperties(); // 4.创建事件集合 this.earlyApplicationEvents = new LinkedHashSet
(); }

来看下 initPropertySources 这个方法, 它与 Spring 容器的 Environment 有关:

protected void initPropertySources() {    // 取得配置过程中创建的容器环境    ConfigurableEnvironment env = getEnvironment();    // 初始化 Environment 的 propertySources 属性 if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment) env). initPropertySources(this.servletContext, this.servletConfig); } }

创建内部容器

之前介绍过 ApplicationContext 对象里面会包含了一个 BeanFactory 对象。有关 Bean 的基本功能是调用内部的 BeanFactory 对象来实现的。

在这里, BeanFactory 具体指的是 ConfigurableListableBeanFactory ,来看它们的继承关系:

Alt text


下面来看 obtainFreshBeanFactory 的具体实现:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {    // 1.刷新 BeanFactory    refreshBeanFactory();    // 2.取得 BeanFactory    ConfigurableListableBeanFactory beanFactory = getBeanFactory();    // 省略部分代码... return beanFactory; }

1.刷新 BeanFactory

下面来看刷新内部 BeanFactory 的实现过程:

protected final void refreshBeanFactory() throws BeansException { // 1.判断是否存在 Beanfactory ,存在则销毁并关闭它 if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { // 2.创建 BeanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); // 3.设置 BeanFactory 的 id,同它外部的 Spring 容器一致 beanFactory.setSerializationId(getId()); // 4.定制 BeanFactory 初始化,暂不探究 customizeBeanFactory(beanFactory); // 5.加载 Bean 实例 loadBeanDefinitions(beanFactory); // 6.将 BeanFactory 设置为 Spring 容器的内部 BeanFactory synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } }catch (IOException ex) { // 抛出异常... } }

①判断是否存在 BeanFactory,存在则销毁、关闭容器的内部 BeanFactory

// 1.判断是否存在存在内部 BeanFactoryprotected final boolean hasBeanFactory() { synchronized (this.beanFactoryMonitor) { return (this.beanFactory != null); } } // 2.若存在销毁内部 BeanFactory 的所有 Bean protected void destroyBeans() { getBeanFactory().destroySingletons(); } // 2.关闭 内部 BeanFactory protected final void closeBeanFactory() { synchronized (this.beanFactoryMonitor) { this.beanFactory.setSerializationId(null); this.beanFactory = null; } }

②创建 BeanFactory,这里会默认创建 DefaultListableBeanFactory 类作为内部容器(内部 BeanFactory)。

protected DefaultListableBeanFactory createBeanFactory() {    // 1.取得内部 BeanFactory 的父容器     // 2.创建内部 BeanFactory    return new DefaultListableBeanFactory(getInternalParentBeanFactory()); } protected BeanFactory getInternalParentBeanFactory() { // 判断取得 Spring 容器的父容器类型 // 匹配,则返回父容器内部 BeanFactory,否则返回父容器 return (getParent() instanceof ConfigurableApplicationContext) ? ((ConfigurableApplicationContext) getParent()).getBeanFactory() :getParent(); } public DefaultListableBeanFactory(BeanFactory parentBeanFactory) { super(parentBeanFactory); } public AbstractAutowireCapableBeanFactory(BeanFactory parentBeanFactory) { this(); setParentBeanFactory(parentBeanFactory); }

Alt text


③加载 Bean 实例,该过程由 BeanDefinitionReader 负责,下篇在详细分析。


2.取得 BeanFactory

// 取得 BeanFactorypublic final ConfigurableListableBeanFactory getBeanFactory() {    synchronized (this.beanFactoryMonitor) { if (this.beanFactory == null) { // 抛出异常... } return this.beanFactory; } }

总结

下面通过流程图来总结下 Spring Ioc 容器的初始化过程:

Alt text

转载于:https://www.cnblogs.com/moxiaotao/p/9349506.html

你可能感兴趣的文章
NPOI操作Excel导入导出
查看>>
angularJS 移动端焦点图
查看>>
jvm 这我就能会了 擦
查看>>
实战技能:小小微信支付业务,何必虚惊一场
查看>>
17-1 djanjo进阶-路由,视图,模板
查看>>
Shell脚本8种字符串截取方法总结
查看>>
P3254 圆桌问题
查看>>
MapReduce的运行原理
查看>>
Leetcode: Partition List
查看>>
故障转移
查看>>
清空dataset中的某行某列的数据
查看>>
盒模型
查看>>
js中闭包和作用域
查看>>
CI框架整合UEditor编辑器上传功能
查看>>
树的层号表示
查看>>
最大整数
查看>>
[转] 数据模型建设的几点思考与总结
查看>>
[1].Common SSIS Applications
查看>>
Asp.NetCore取配置信息
查看>>
自动变量提示
查看>>