一个简单的Spring容器初始化流程详解

前言

首先我们初始化一个最简单的容器,用这个容器研究初始化的流程。

下面就是一个再简单不过的IoC容器了,该容器包含了一个名为beanA的bean,我们初始化容器后,取出该Bean,并调用方法。

public class BeanA {
 private String testStr = "Test";
 public BeanA(){
  System.out.println("Running A");
 }
 public void sayHello(){
  System.out.println("I'm beanA.");
 }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

 <bean id="beanA" class="cn.jirath.learn.spring.BeanA">
 </bean>
</beans>
@Test
void testHello(){
 Resource springResource=new ClassPathResource("spring-beans.xml");
 BeanFactory beanFactory=new XmlBeanFactory(springResource);
 BeanA beanA= (BeanA) beanFactory.getBean("beanA");
	beanA.sayHello();
}

虽然XmlBeanFactory已经被Spring标记为过时,但是为了达到我们从一个xml定义的bean信息构造一个BeanFactory的目的,勉为其难,还是先用一下233。

这段代码很简单,但是反映了我们使用IoC的一个基础流程:

  1. 选择并构建数据源
  2. 利用数据源构建一个容器
  3. 取出Bean使用

我们就先从这几点一点点讲

在开始之前,需要意识到的是:Spring作为一款优秀的面向对象的框架设计,Spring中采用了大量的设计模式并按照面向对象的逻辑对各个类进行设计,做到了各个类功能单一。

这意味着,Spring的代码会有一种剥洋葱的感觉,子类对双亲扩展,调用默认实现。

选择并构建数据源

构建数据源的部分难度不大,会稍微简单点讲

这里推荐一本书:《Spring源码深度解析(第2版)》

看了Spring的设计,这是真的面向对象。

Spring一开始是使用大量的xml文件配置了容器。从面向对象的角度思考,为了方便使用,需要将各种资源都被抽象出来,先看一下他的资源类结构体系。该部分是系统最底层,在core包中

InputStreamSource封装能返回InputStream的类,可以返回这个流。

日常开发用Spring的体系也会很便捷。

Resource体系达到了这样的目的:对于不同的文件来源都有一种实现来读取该文件,同时,拥有一个规范的接口。

现在我们有了Resource的设计,为了读取对象,Spring提供了BeanDefinitionReader、ResourceLoader来从资源中提取出我们需要的资源内容。这些类的关系如下:

  1. Resource代表一个资源对象
  2. ResourceLoader将文件转化为Resource对象
  3. DocumentLoader将Resource对象转化为Document对象
  4. BeanDefinitionDocumentReader解析Document对象为BeanDefinitions
  5. BeanDefinitionReader抗了初始化的大梁,在new的时候会绑定一个Bean定义注册器(DefaultListableBeanFactory实现了他),后面解析后会用这个注册器注册

这就是大致的一个逻辑,把握住这个大致的逻辑看源码,体验要上升不少

下面是最上方的例子启动的大致的流程,大量的代码在处理读取资源的逻辑

  1. Resource代表一个资源对象
  2. Resource封装为带编码格式的EncodedResource对象
  3. XmlBeanDefinitionReader构建Document对象
  4. XmlBeanDefinitionReader内部有个DocumentLoader,读取Resource对象转化为Document对象
  5. ResourceLoader将文件转化为Resource对象
  6. DocumentLoader将Resource对象转化为Document对象
  7. Document对象转为Element对象
  8. DocumentReader读取Element对象,将信息存储在BeanDefinitionParserDelegate
  9. DocumentReader解析BeanDefinitionParserDelegate为BeanDefinitionHolder
  10. BeanDefinitionHolder获取BeanDefinitions,交给register进行注册(加锁、放map)。
  11. 返回注册的数量

这里就是初始化的结果了

总结

到此这篇关于一个简单的Spring容器初始化流程的文章就介绍到这了,更多相关Spring容器初始化流程内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot 如何添加容器启动的初始化逻辑的操作方法

    背景 传统 SpringMVC 项目中,我们可以定义容器初始化 Servlet ,然后在 web.xml 配置该 Servlet ,指定 load-on-startup 就可以在容器启动后,执行一些系统的初始化逻辑.比如设置全局资源文件路径.加载系统定时任务.数据初始化等. 技术转换到 SpringBoot 的时候,该在哪里添加应用初始化的代码呢? 如果初始化逻辑中,有一些普通类,需要通过 Spring 的 ApplicationContext 的 getBean 获取依赖属性,如何保证 Spr

  • 浅谈spring容器中bean的初始化

    当我们在spring容器中添加一个bean时,如果没有指明它的scope属性,则默认是singleton,也就是单例的. 例如先声明一个bean: public class People { private String name; private String sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public String get

  • Spring容器初始化及问题解决方案

    1.Spring bean组件 "默认为单例模式scope="singleton, 运行JavaApplication容器启动时自动创建对象 scope="prototype"为多例模式,请求条件下才创建对象 2beans组件 里面default-init-method初始化方法加载,范围比较大,当没有此方法时不会报错,default-destroy-method销毁方法,default-lazy-init="true/false" 对象延时实例

  • 理解 MyBatis 是如何在 Spring 容器中初始化的

    MyBatis 初始化过程就是生成一些必须的对象放到 Spring 容器中.问题是这个过程到底生成了哪些对象?当遇到 MyBatis 初始化失败时,如何正确的找到分析问题的切入点?本文将针对这些问题进行介绍. 本文基于 MyBatis 3 和 Spring,假设读者已经知道如何使用 Maven 和 MyBatis,以及了解 Spring 的容器机制. 一.Mybatis 三件套 我们知道 MyBatis 的主要功能是由 SqlSessionFactory 和 Mapper 两者提供的,初始化 M

  • 浅谈Spring与SpringMVC父子容器的关系与初始化

    Spring和SpringMVC的容器具有父子关系,Spring容器为父容器,SpringMVC为子容器,子容器可以引用父容器中的Bean,而父容器不可以引用子容器中的Bean. 了解了Spring与SpringMVC父子容器的关系,接下来让我们看看Spring与SpringMVC容器的初始化过程. 以下讲解使用的web.xml文件如下: <context-param> <param-name>contextConfigLocation</param-name>//指定

  • spring容器初始化遇到的死锁问题解决

    前言 最近启动spring项目的时候遇到一个死锁问题,使用jstack获取线程堆栈的时候,可以看到2个线程出现了死锁: 解决过程: DefaultSingletonBeanRegistry.getSingleton()源码如下,可以看到这个方法需要对singletonObjects加锁 第二处xxx.subject.core.cache.DataLocalcacheInit.afterPropertiesSet源码如下: 可以看到:这个bean在初始化的时候,会开启线程,调用另外一个bean的i

  • 一个简单的Spring容器初始化流程详解

    前言 首先我们初始化一个最简单的容器,用这个容器研究初始化的流程. 下面就是一个再简单不过的IoC容器了,该容器包含了一个名为beanA的bean,我们初始化容器后,取出该Bean,并调用方法. public class BeanA { private String testStr = "Test"; public BeanA(){ System.out.println("Running A"); } public void sayHello(){ System.o

  • 简单实现Spring的IOC原理详解

    控制反转(InversionofControl,缩写为IoC) 简单来说就是当自己需要一个对象的时候不需要自己手动去new一个,而是由其他容器来帮你提供:Spring里面就是IOC容器. 例如: 在Spring里面经常需要在Service这个装配一个Dao,一般是使用@Autowired注解:类似如下 public Class ServiceImpl{ @Autowired Dao dao; public void getData(){ dao.getData(); } 在这里未初始化Dao直接

  • 使用JSP技术实现一个简单的在线测试系统的实例详解

    1.登陆界面 实现: 本界面由三部分构成,Footer.jsp,Index.jsp,Header.jsp Header.jsp <center> <h2>在线测试系统</h2> <p> <a href="Index.jsp" rel="external nofollow" >登录</a> | <a href="test.jsp" rel="external n

  • Spring中Bean的加载与SpringBoot的初始化流程详解

    目录 前言 第一章 Spring中Bean的一些简单概念 1.1 SpingIOC简介 1.2 BeanFactory 1.2.1 BeanDefinition 1.2.2 BeanDefinitionRegistry 1.2.3 BeanFactory结构图 1.3 ApplicationContext 第二章 SpringBoot的初始化流程 2.1 准备阶段 2.2 运行阶段 2.2.1 监听器分析 2.2.2 refreshContext 2.3 总结 前言 一直对它们之间的关系感到好奇

  • Delphi下OpenGL2d绘图之初始化流程详解

    一.前言: Delphi默认支持OpenGl,可以使用uses OpenGL单元进行引用,之后就可以使用OpenGL的函数.OpenGl是跨平台的,而且Windows很早就支持并集成在系统中,存在于system32中的opengl32.dll,不需要再额外进行安装.虽然windows本身有d3d,但是其能力有限,相关学习资料页相对较少. 通常OpenGL仅仅支持以下几种基本几何图形:点,线和多边形.没有表面或者更高级的图形(比如球状图形)能被作为基本图形元素绘制.但是它们能够用多边形来完美的模仿

  • 用java的spring实现一个简单的IOC容器示例代码

    要想深入的理解IOC的技术原理,没有什么能比的上我们自己实现它.这次我们一起实现一个简单IOC容器.让大家更容易理解Spring IOC的基本原理. 这里会涉及到一些java反射的知识,如果有不了解的,可以自己去找些资料看看. 注意 在上一篇文章,我说,启动IOC容器时,Spring会将xml文件里面配置的bean扫描并实例化,其实这种说法不太准确,所以我在这里更正一下,xml文件里面配置的非单利模式的bean,会在第一次调用的时候被初始化,而不是启动容器的时候初始化.但是我们这次要做的例子是容

  • Spring Bean是如何初始化的详解

    目录 前言 三级缓存 doGetBean createBean doCreateBean instantiateBean instantiate instantiateClass 注入 AutowiredAnnotationBeanPostProcessor分析 postProcessProperties 如何实现bean注入的 总结 前言 做Java都有很多年了,一直有一个疑惑: Spring 如何初始化bean,怎么调用反射实例化对象的,自己动手来解除这个疑惑. 过去我认为spring be

  • Spring 容器初始化 register 与 refresh方法

    目录 register方法 refresh 方法 1.prepareRefresh 2.obtainFreshBeanFactory 3.prepareBeanFactory 4.postProcessBeanFactory 5.invokeBeanFactoryPostProcessors 6.registerBeanPostProcessors 7.非重点部分 前篇回顾: Spring源码解析容器初始化构造方法 在上一篇文章中,我们介绍完了AnnotationConfigApplicatio

  • MyBatis集成Spring流程详解

    目录 一.Mybatis与spring集成 1. 导入pom依赖 2. 编写配置文件 3. 使用注解开发 4. 测试 5. 管理数据源 二.Aop整合pagehelper插件 要解决的问题 一.Mybatis与spring集成 1. 导入pom依赖 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8

  • Android 实例开发一个学生管理系统流程详解

    目录 效果演示 实现功能总览 代码 登录与忘记密码界面 一.添加布局文件 二.添加标题文字 三.绑定适配器 注册界面 一.创建两个Drawable文件 二.将其添加数组内 三.动态变化背景 考勤界面 一.CircleProgressBar代码如下 签到界面 一.倒计时 二.位置签到 成绩查询界面 一.创建StackAdapter 适配器 效果演示 随手做的一个小玩意,还有很多功能没有完善,倘有疏漏,万望海涵. 实现功能总览 实现了登录.注册.忘记密码.成绩查询.考勤情况.课表查看.提交作业.课程

随机推荐