本系列文章将逐一介绍,Spring容器创建到容器刷新完成每个过程。

Spring容器继承结构图

第一步,new容器实例

ApplicationContext factory = new ClassPathXmlApplicationContext("classpath:application.xml");

容器构造器

 public ClassPathXmlApplicationContext(String configLocation) throws BeansException {// 配置路径转为String数组,刷新容器,父容器为nullthis(new String[] {configLocation}, true, null);}

最终调用的构造器

 public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)throws BeansException {super(parent);// 检测解析一下配置文件,保存配置文件路径在 this.configLocations 属性中setConfigLocations(configLocations);if (refresh) {// 容器启动的关键步骤,刷新容器refresh();}}

refresh()

refresh()方法中完成Spring容器的初始化,事件的派发,bean生命周期管理。是容器创建最重要的一个步骤。方法的实现在AbstractApplicationContext中,这个系列将逐个方法的介绍。

refresh方法概览:可直接跳过。

     synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);// Initialize message source for this context.initMessageSource();// Initialize event multicaster for this context.initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.onRefresh();// Check for listener beans and register them.registerListeners();// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// 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();}}

prepareRefresh();

refresh()中的第一个方法调用,prepareRefresh,做刷新容器前的准备工作。
废话不说,直接看源码。

 protected void prepareRefresh() {// 设置容器启动时间this.startupDate = System.currentTimeMillis();// 设置容器激活标记this.closed.set(false);this.active.set(true);if (logger.isInfoEnabled()) {logger.info("Refreshing " + this);}// 留给子类initPropertySources();// 获取运行环境,验证属性getEnvironment().validateRequiredProperties();// 创建一个链表存放容器早期事件this.earlyApplicationEvents = new LinkedHashSet<>();}
getEnvironment()

getEnvironment最终获取一个StandardEnvironment。

 @Overridepublic ConfigurableEnvironment getEnvironment() {if (this.environment == null) {this.environment = createEnvironment();}return this.environment;}protected ConfigurableEnvironment createEnvironment() {return new StandardEnvironment();}

StandardEnvironment类型结构

Environment接口代表当前应用所处环境,springBean支持和一个Profile绑定,方便与测试环境开发环境切换。

PropertyResolver中的Property指程序运行时的参数,如系统参数,JVM参数等

StandardEnvironment构造器中做了些什么

// 在构造器中,初始化一些定制属性public AbstractEnvironment() {// 方法在StandardEnvironment中实现// this.propertySources是一个MutablePropertySources用于保存属性customizePropertySources(this.propertySources);if (logger.isDebugEnabled()) {logger.debug("Initialized " + getClass().getSimpleName() + " with PropertySources " + this.propertySources);}}

在StandardEnvironment中实现了定制属性方法

 @Overrideprotected void customizePropertySources(MutablePropertySources propertySources) {     // 添加系统属性propertySources.addLast(new MapPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));// 添加系统环境propertySources.addLast(new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));}

validateRequiredProperties 验证属性

getEnvironment()得到一个StandardEnvironment,然后调用它父类的的ValidateRequiredProperties进行属性验证。

 @Overridepublic void validateRequiredProperties() throws MissingRequiredPropertiesException {this.propertyResolver.validateRequiredProperties();}
// AbstractEnvironment的解析器
private final ConfigurablePropertyResolver propertyResolver =new PropertySourcesPropertyResolver(this.propertySources);// 在StandarEnvironment父类AbstractEnvironment中@Overridepublic void validateRequiredProperties() throws MissingRequiredPropertiesException {this.propertyResolver.validateRequiredProperties();}@Overridepublic void validateRequiredProperties() {MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();// 验证是否缺少属性值for (String key : this.requiredProperties) {if (this.getProperty(key) == null) {ex.addMissingRequiredProperty(key);}}if (!ex.getMissingRequiredProperties().isEmpty()) {throw ex;}}

Spring容器创建流程(1)容器创建准备相关推荐

  1. android opengl流程,【Android OpenGL ES】Android Opengl ES创建流程

    在android 1.0rc2 sdk中,提供了以下包支持Opengl ES 编程: 一.openglES包 android.opengl Class: GLDebugHelper:用于调试OpenG ...

  2. spring系列-注解驱动原理及源码-spring容器创建流程

    目录 一.spring容器的refresh()[创建刷新] 二.BeanFactory 的创建及预准备工作 1.prepareRefresh()刷新前预处理工作. 2.obtainFreshBeanF ...

  3. Spring容器创建流程(8)初始化bean

    finishBeanFactoryInitialization(beanFactory); 很重要的一步,初始化剩余未初始化的bean(还没有创建实例放到容器中的). 容器refresh总览: syn ...

  4. 分析Spring容器启动流程 Spring初始化

    分析Spring容器启动流程 Spring初始化 每当启动Web容器时(例如Tomcat),会读取Web应用中的web.xml文件.以下这段代码就是启动Spring容器的关键代码. ContextLo ...

  5. 阿里面试真题:Spring容器启动流程

    有情怀,有干货,微信搜索[三太子敖丙]关注这个不一样的程序员. 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试完整考点.资料以及我的系列文章. ...

  6. Spring的初始化和对象创建流程

    Spring容器的初始化和对象创建流程(代码方面): 如图: 1.Spring容器初始化流程: 文字说明: 在ClassPathXmlApplicationContext的构造函数中: super(p ...

  7. Spring(二)IOC容器的初始化流程

    文章目录 一.Spring 核心容器类 1.1 BeanFactory 1.2 ApplicationContext 1.3 BeanDefinition 二.IOC容器的初始化 2.1 基于Xml的 ...

  8. 什么是Spring三级缓存 对象在三级缓存中的创建流程 【三级缓存 循环依赖】

    一.什么是Spring三级缓存 第一级缓存:也叫单例池,存放已经经历了完整生命周期的Bean对象. 第二级缓存:存放早期暴露出来的Bean对象,实例化以后,就把对象放到这个Map中.(Bean可能只经 ...

  9. Spring容器启动流程+Bean的生命周期【附源码】

    如果对SpringIoc与Aop的源码感兴趣,可以访问参考:https://javadoop.com/,十分详细. 文章目录 Spring容器的启动全流程 Spring容器关闭流程 Bean 的生命周 ...

  10. Spring源码分析2 — 容器启动流程

    1 主要类 部署web应用时,web容器(比如Tomcat)会读取配置在web.xml中的监听器,从而启动spring容器.有了spring容器之后,我们才能使用spring的IOC AOP等特性.弄 ...

最新文章

  1. sqlserver的索引创建
  2. 设计模式之职责链模式永不罢休(二十一)
  3. MySQL索引(B+Tree 索引、哈希索引、全文索引、 空间数据索引)、索引优化、优点、使用场景
  4. 统计Apache或nginx日志里访问次数最多的前十个IP
  5. 在解决计算机主机,电脑主机噪音大怎么办 电脑主机噪音大解决方法【图文】...
  6. 怎么做笔记标签贴_小红书笔记互动到底该怎么做?
  7. 项目案例:在线拍卖系统_冀拓公司在张家口开展尾矿库在线监测监控系统 建设项目...
  8. nvidia-smi‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件
  9. 神经网络-损失函数-等高线理解
  10. 机器学习顶刊文献_“大数据+机器学习”在光催化制氢中的研究范式
  11. MYSQL多线程插入操作
  12. asp.net网站后台退出后,点后退按钮仍能进,如何安全退出
  13. GB35114---SM3withSM2证书生成及读取(二)
  14. Android6.0源码下载
  15. Word设置封面无页码,摘要罗马数字页码,正文数字页码
  16. unity利用帧动画制作特效
  17. python当前运行目录_Python获取运行目录与当前脚本目录的方法
  18. RocketMQ初识
  19. php date()时间不对,PHP DATE( )函数与系统时间差8小时解决办法
  20. Linux C报错: /usr/bin/ld: cannot find -ldb

热门文章

  1. 国产“电动牦牛”亮相,负重 160 公斤健步如飞!
  2. SQL Server “Denali” ---SQL 2012 新特性
  3. url传递中文的解决方案总结
  4. 理想汽车CEO李想晒11月理想ONE成绩
  5. 网易云音乐IPO拟至少募30.4亿港元 开售半日已获足额认购
  6. 创维发布四款新品 将投入65亿元建MiniLED显示科技产业园
  7. 微博发布公告 将开展财经违规内容专项整治行动
  8. 格力电器Q3净利润73.37亿元 同比下降12.32%
  9. AMD官宣350亿美元收购赛灵思 赛灵思大涨8.56%
  10. 三星Galaxy Note20系列再遭减配:100倍变焦也没了