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

 更新时间:2021年1月25日 10:00  点击:1702

前言

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

下面就是一个再简单不过的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容器初始化流程内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

[!--infotagslink--]

相关文章

  • Spring AOP 对象内部方法间的嵌套调用方式

    这篇文章主要介绍了Spring AOP 对象内部方法间的嵌套调用方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-08-29
  • Spring Cloud 中@FeignClient注解中的contextId属性详解

    这篇文章主要介绍了Spring Cloud 中@FeignClient注解中的contextId属性详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-25
  • Springboot如何实现Web系统License授权认证

    这篇文章主要介绍了Springboot如何实现Web系统License授权认证,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-28
  • 如何在Spring WebFlux的任何地方获取Request对象

    这篇文章主要介绍了如何在Spring WebFlux的任何地方获取Request对象,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下...2021-01-26
  • 详解SpringCloudGateway内存泄漏问题

    这篇文章主要介绍了详解SpringCloudGateway内存泄漏问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-16
  • Spring为什么不推荐使用@Autowired注解详析

    @Autowired 注解的主要功能就是完成自动注入,使用也非常简单,但这篇文章主要给大家介绍了关于Spring为什么不推荐使用@Autowired注解的相关资料,需要的朋友可以参考下...2021-11-03
  • Springboot如何使用mybatis实现拦截SQL分页

    这篇文章主要介绍了Springboot使用mybatis实现拦截SQL分页,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-19
  • 解决vuex数据页面刷新后初始化操作

    这篇文章主要介绍了解决vuex数据页面刷新后初始化操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-26
  • Vue初始化中的选项合并之initInternalComponent详解

    这篇文章主要介绍了Vue初始化中的选项合并之initInternalComponent的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-06-11
  • SpringMVC文件上传原理及实现过程解析

    这篇文章主要介绍了SpringMVC文件上传原理及实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-07-15
  • Spring Data JPA 关键字Exists的用法说明

    这篇文章主要介绍了Spring Data JPA 关键字Exists的用法说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-06-10
  • C#中数组初始化与数组元素复制的方法

    这篇文章主要介绍了C#中数组初始化与数组元素复制的方法,涉及C#中数组的创建、初始化及使用Array.Copy方法复制数组元素的技巧,需要的朋友可以参考下...2020-06-25
  • 教你使用Portainer管理多台Docker容器环境的方法

    这篇文章主要介绍了Portainer管理多台Docker容器环境,本文给大家介绍的非常详细,包括环境准备及管理docker的详细过程,需要的朋友可以参考下...2021-11-11
  • tomcat启动完成执行 某个方法 定时任务(Spring)操作

    这篇文章主要介绍了tomcat启动完成执行 某个方法 定时任务(Spring)操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-25
  • 使用Maven 搭建 Spring MVC 本地部署Tomcat的详细教程

    这篇文章主要介绍了使用Maven 搭建 Spring MVC 本地部署Tomcat,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-08-16
  • Java Spring Cloud 负载均衡详解

    这篇文章主要介绍了Spring Cloud负载均衡及远程调用实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2021-09-18
  • SpringMvc自动装箱及GET请求参数原理解析

    这篇文章主要介绍了SpringMvc自动装箱及GET请求参数原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-19
  • SpringMvc获取请求头请求体消息过程解析

    这篇文章主要介绍了SpringMvc获取请求头请求体消息过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-17
  • Springboot使用thymeleaf动态模板实现刷新

    这篇文章主要介绍了Springboot使用thymeleaf动态模板实现刷新,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-08-31
  • Idea打包springboot项目没有.original文件解决方案

    这篇文章主要介绍了Idea打包springboot项目没有.original文件解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-07-26