基本概念梳理

IoC(Inversion of Control,控制反转)就是把原来代码里需要实现的对象创建、依赖,反转给容器来帮忙实现。我们需要创建一个容器,同时需要一种描述来让容器知道要创建的对象与对象的关系。这个描述最具体的表现就是我们所看到的配置文件。

DI(Dependency Injection,依赖注入)就是指对象被动接受依赖类而不自己主动去找,换句话说,就是指对象不是从容器中查找它依赖的类,而是在容器实例化对象时主动将它依赖的类注入给它。

撇开Spring源码不看,从我们自身的理解出发,如果我们来开发这样的容器,需要考虑下面几个问题:

  • 对象与对象的关系怎么表示?

答案:可以用XML、Properties等语义化的配置文件来表示。

  • 描述对象关系的文件存放在哪里?

答案:可以是Classpath、FileSystem、URL网络资源或者servletContext等。

  • 不同的配置文件对对象的描述不一样,如标准的、自定义声明式的,如何统一?

答案:这就可能在内部需要有一个统一的关于对象的定义,所有外部的描述都必须转化成统一的描述定义。

  • 如何对不同的配置文件进行解析?

答案:需要对不同的配置文件语法采用不同的解析器。

Spring核心容器类图

1、BeanFactory

Spring中Bean的创建是典型的工厂模式,这一系列的Bean工厂,即IoC容器,为开发者管理对象之间的依赖关系提供了很多便利和基础服务,在Spring中有许多IoC容器的实现供用户选择,其相互关系如下图所示。

其中,BeanFactory作为最顶层的一个接口类,定义了IoC容器的基本功能范围,BeanFactory有三个重要的子类:ListableBeanFactory、
HierarchicalBeanFactory和AutowireCapableBeanFactory。但是从类图中我们可以发现最终的默认实现类是DefaultListableBeanFactory,它实现了所有的接口。那么为何要定义这么多层次的接口呢?查阅这些接口的源码和说明发现,每个接口都有它的使用场合,主要是为了区分在Spring内部操作过程中对象的传递和转化,对对象的数据访问所做的限制。

例如,ListableBeanFactory接口表示这些Bean可列表化,而HierarchicalBeanFactory表示这些Bean 是有继承关系的,也就是每个Bean 可能有父 Bean。AutowireCapableBeanFactory 接口定义Bean的自动装配规则。这三个接口共同定义了Bean的集合、Bean之间的关系及Bean行为。最基本的IoC容器接口是BeanFactory,来看一下它的源码:

查看代码

package org.springframework.beans.factory; import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable; public interface BeanFactory { //对FactoryBean的转义定义,因为如果使用Bean名字来进行搜索FactoryBean的话得到的只是工厂生成的对象
//如果需要得到工厂本身,需要转义
String FACTORY_BEAN_PREFIX = "&"; //根据Bean的名字获得在IoC容器种的Bean的实例
Object getBean(String name) throws BeansException; //根据Bean的名字和Class类型来得到Bean的实例,同时增加了类型安全验证机制
<T> T getBean(String name, Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; <T> T getBean(Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType); <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType); //提供对Bean的检索,看下具备Bean的名字的Bean是否存在于IoC容器中
boolean containsBean(String name); //判断具备name的Bean是否存在于容器,并且是否是单例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException; //判断具备name的Bean是否存在于容器,并且是否是原型
boolean isPrototype(String name) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException; //得到Bean实例的Class类型
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException; @Nullable
Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException; //得到Bean实例在IoC容器中的别名,当然你输入别名来搜索,结果原名也会包含其中
String[] getAliases(String name); }

从上面可以看出,在BeanFactory里只对IoC容器的基本行为做了定义,根本不关心你的Bean是如何定义及怎样加载的。正如我们只关心能从工厂里得到什么产品,不关心工厂是怎么生产这些产品的。要知道工厂是如何产生对象的,我们需要看具体的IoC容器实现,Spring里面提供了许多IoC容器实现,比如GenericApplicationContext、ClasspathXmlApplicationContext等。

PS:ApplicationContext是Spring提供的一个高级的IoC容器,它除了能够提供IoC容器的基本功能,还为用户提供了以下附加服务。

  1. 支持信息源,可以实现国际化(实现MessageSource接口)。
  2. 访问资源(实现ResourcePatternResolver接口,后面系列会讲到)。
  3. 支持应用事件(实现ApplicationEventPublisher接口)。

2、BeanDifinition

Spring IoC容器管理我们定义的各种Bean对象及其相互关系,Bean对象在Spring实现中是以BeanDefinition来描述的,其继承体系如下图所
示。

3、BeanDefinitionReader

Bean的解析过程非常复杂,功能被分得很细,因为这里需要被扩展的地方很多,必须保证足够的灵活性,以应对可能的变化。Bean的解析
主要就是对Spring配置文件的解析。这个解析过程主要通过BeanDefinitionReader来完成,看看Spring中BeanDefinitionReader的类结构图,如下图所示。

总结

通过前面的分析,我们对Spring框架体系有了一个基本的宏观了解,希望可以好好理解,最好在脑海中形成画面,为后面的学习
打下良好的基础。

Spring5源码解析系列一——IoC容器核心类图的更多相关文章

  1. Spring源码解析三:IOC容器的依赖注入

    一般情况下,依赖注入的过程是发生在用户第一次向容器索要Bean是触发的,而触发依赖注入的地方就是BeanFactory的getBean方法. 这里以DefaultListableBeanFactory ...

  2. Spring源码解析一:IOC容器设计

    一.IOC接口设计 IOC容器设计的源码主要在spring-beans.jar.spring-context.jar这两个包中.IOC容器主要接口设计如下: 这里的接口设计有两条主线:BeanFact ...

  3. Spring源码解析二:IOC容器初始化过程详解

    IOC容器初始化分为三个步骤,分别是: 1.Resource定位,即BeanDefinition的资源定位. 2.BeanDefinition的载入 3.向IOC容器注册BeanDefinition ...

  4. Spring源码分析(三)容器核心类

    摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 在上一篇文章中,我们熟悉了容器的基本用法.在这一篇,我们开始分析Spri ...

  5. Spring源码解析系列汇总

    相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的Spring源码解析系列文章的汇总,总共包含以下专题.喜欢的同学可以收藏起来以备不时之需 SpringIOC源码解析(上) 本篇文章搭建了IOC源 ...

  6. Spring5源码解析-Spring框架中的单例和原型bean

    Spring5源码解析-Spring框架中的单例和原型bean 最近一直有问我单例和原型bean的一些原理性问题,这里就开一篇来说说的 通过Spring中的依赖注入极大方便了我们的开发.在xml通过& ...

  7. Spring5源码解析-论Spring DispatcherServlet的生命周期

    Spring Web框架架构的主要部分是DispatcherServlet.也就是本文中重点介绍的对象. 在本文的第一部分中,我们将看到基于Spring的DispatcherServlet的主要概念: ...

  8. 【原】Android热更新开源项目Tinker源码解析系列之三:so热更新

    本系列将从以下三个方面对Tinker进行源码解析: Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Android热更新开源项目Tinker源码解析系列之二:资源文件热更新 A ...

  9. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

随机推荐

  1. ElasticSearch、Kibana 介绍&安装

    目录 ElasticSearch 介绍 基于数据库查询的问题 倒排(反向)索引 ES 存储和查询的原理 ES 核心概念 ES 安装 Kibana ElasticSearch 介绍 基于数据库查询的问题 ...

  2. Jenkins_构建任务提示找不到命令的处理方法

    问题现象 部署pytest环境后,在linux上能执行命令,但是使用jenkins构建就提示找不到命令. 问题分析 可能是...jenkins中执行时,默认使用的是linux中的jenkins用户权限 ...

  3. mongodb用户权限管理的CRUD

    https://blog.csdn.net/weixin_34332905/article/details/88759759?utm_medium=distribute.pc_relevant.non ...

  4. 实验 1 :Mininet 源码安装和可视化拓扑

    实验 1 : Mininet 源码安装和可视化拓扑工具 一 .实验目的 掌握 Mininet 的源码安装方法和 miniedit 可视化拓扑生成工具. 二 .实验任务 使用源码安装 Mininet 的 ...

  5. 关于在Vue中使用WebScoket的随笔

    声明:请勿直接复制粘贴抄袭文章,若有需要,请规范转载,注明出处,谢谢! ---------------------------------------------------------------- ...

  6. Sharding Sphere的分库分表

    什么是 ShardingSphere? 1.一套开源的分布式数据库中间件解决方案 2.有三个产品:Sharding-JDBC 和 Sharding-Proxy 3.定位为关系型数据库中间件,合理在分布 ...

  7. Spring系列1:Spring基本概念

    本文内容 什么是Spring? 为什么学Spring? 本系列包含哪些技术? 本系列适合哪些人? 什么是Spring? 基本概念 Spring 框架为现代基于 Java 的企业应用程序提供了一个全面的 ...

  8. 校招——面试(Android岗)总结

    PS:持续更新,未完待续 2016.8.24某为面试 自我介绍一下 链表和数组的区别 数组的存储空间是静态.连续分布的,初始化过大会造成空间浪费,过小会使空间溢出:链表的存储空间是动态分布的,只要内存 ...

  9. day1 三位数各个位上的数字和

    int main(){ int x = 0; scanf("%d", &x); if (x > 999 || x < 0) { printf("输入错 ...

  10. es基础知识

    1.ES定义 •是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储.检索数据:本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据 •使用Java开发并使用Lucene作为其核心来实现 ...