首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring框架源码脉络分析(一):IoC与容器、Bean和BeanDefinition

Spring框架源码脉络分析(一):IoC与容器、Bean和BeanDefinition

作者头像
星如月勿忘初心
发布2020-08-02 11:17:07
7570
发布2020-08-02 11:17:07
举报
文章被收录于专栏:星月小站星月小站

系列文章概述

  • 系列文章主页:Spring框架源码脉络分析总结
  • 阅读建议:读者至少要使用过Spring框架,了解Spring的配置方法,包括Xml文件配置和注解配置。
  • 分析的源码版本:spring-framework : 5.2.0.RELEASE
  • 官方参考文档:Spring Framework Documentation
  • 本文主要以分析Spring源码模块脉络为主,主要带领读者理清Spring运行的流程和脉络,不会深究一些知识细节,避免陷入细节无法自拔,所以仅贴出来核心的源码进行分析备注,对于每个步骤的细节,需要读者自行深入了解

IoC与容器

IoC:即控制反转机制。在Spring中的实现表现为IoC容器,属于Spring Core模块最核心的部分。

在这里插入图片描述
在这里插入图片描述

IoC其实是一种设计思想,其本质就是将对象的创建、依赖关系的管理以及生命周期的的控制交由IoC容器,或者说是框架来管理,解放了码农的双手。

IoC的存在离不开另外一个设计思想——依赖注入(DI)。

  1. 依赖注入最直观的解释就是一个实例化对象只接受一个参数——已经实例化的对象。也就是说一个对象A中如果依赖另一个对象B,必须直接注入一个已经实例化的对象B,对象A本身不关注对象B如何实例化的,这样就将对象间的依赖尽可能的解耦。
  2. 而控制对象实例化和操作对象注入的【控制】权限就交给了第三方——spring框架,进行控制反转,这就是IoC。
  3. 既然有了这种设计思想,那么对象B是如何注入对象A中去的呢?其实很简单,就是通过四种常用的注入方式:Set注入、接口注入、注解注入和构造器注入。
  4. 所以IoC、依赖反转和IoC容器的关系可以看做下图:
在这里插入图片描述
在这里插入图片描述

IoC在spring中依托于一个类似工厂的IoC容器,将所有的bean都托管在容器中,随时供框架进行调用,spring的容器可以让码农避免在各处使用new来创建类,并且做到了统一维护,码农在创建实例的时候不需要了解其中的细节。

什么是容器:Spring官方文档中对容器的描述如下:

The org.springframework.context.ApplicationContext interface represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the beans.

意思是org.springframework.context.ApplicationContext这个接口就代表了Spring的容器,这个容器负责实例化、配置以及装配一个Bean。

所以简单的从代码上看,我们可以认为容器就是一个ApplicationContext的实现类的实例化对象。当我们使用Spring框架对对象进行管理时,Spring框架会自动为我们创建一个容器用来管理对象,这个容器是Spring框架的核心。我们将在第二章节中重点来分析Spring中的容器类。

Bean和BeanDefinition

在Spring中,Bean是一等公民,我们常说的对象在Spring中就描述为Bean。Bean的本质其实就是Java对象,是我们期望从Spring容器中获取到的实例。

而如果我们去阅读Spring的源码,会发现在Spring中大量操作的是一种名为BeanDefinition的类,而不是Bean。在Spring中,BeanDefinition是对Bean的定义与描述,Bean和BeanDefinition的关系有点像装饰器模式的增强:

  • Spring容器在运行过程中需要对Bean,也就是我们的Java对象进行操作与管理,其中需要进行一些额外的操作,而这些操作在Bean中是没有办法体现的。所以Spring提供了一种无侵入式的方法,对Bean进行包装,将各种描述信息和控制方式信息包装进BeanDefinition中,也就是说BeanDefinition中既有Bean对象的信息,又有描述和控制信息。
  • 那么这些额外的信息是什么呢:其实就是我们经常在xml或者注解文件中使用的配置属性,比如scope属性用来控制Bean是单例还是多例,lazy-init属性用来控制Bean实例是否延迟加载,primary设置为true的Bean将会是类的优先实现类等等。这些额外的信息和参数,就将随着Bean对象一起被封装进BeanDefinition中,以便于Spring根据用户传入的需求对Bean进行管理。

Spring中BeanDefinition的接口体系如下图:

BeanDefinition的接口体系
BeanDefinition的接口体系

其中各接口与类的作用如下:

  • BeanMetadataElement接口: BeanDefinition元数据,定义了返回该Bean的来源的抽象接口。
  • AttributeAccessor接口: 定义了对元数据访问的抽象接口。
  • AttributeAccessorSupport抽象类: AttributeAccessorSupport是实现了AttributeAccessor的抽象类,实现了一些基础通用方法,内部由LinkedHashMap实现。
  • BeanDefinition接口: BeanDefinition体系的顶级基础接口,定义了存储描述Bean的元数据的各种变量与方法,包括Bean的类名、scope属性、是否懒加载等一系列属性。
  • AbstractBeanDefinition抽象类: BeanDefinition接口的抽象实现类,统一实现了BeanDefinition接口定义的一部分操作,定义了BeanDefinition很多默认的属性。同时还继承了BeanMetadataAttributeAccessor类,BeanMetadataAttributeAccessor类又继承自AttributeAccessorSupport,所以AbstractBeanDefinition还同时具备对元数据访问的各种方法实现。正是在AbstractBeanDefinition基础上,Spring又衍生出了一系列的BeanDefinition。Spring框架的设计中,充满了这种通过上下继承关系来对基类进行功能扩充与功能分隔的类体系。

AbstractBeanDefinition上衍生出来的几个类:

  • RootBeanDefinition类: 这是一个可以合并的BeanDefinition,在Spring容器运行期间,容器会对BeanDefinition进行合并,以保证BeanDefinition是最新的,返回的就是RootBeanDefinition。
  • GenericBeanDefinition类: Spring2.5之后出现的通用BeanDefinition实现类,用来操作和返回BeanDefinition,可以灵活设置自己的parentBeanDefinition,而不像RootBeanDefinition一样硬编码,一般我们通过注解配置的bean以及我们的配置类(除@Bean外)的BeanDefiniton类型都是GenericBeanDefinition
  • ChildBeanDefinition类: 现在已经被GenericBeanDefinition所替代了。GenericBeanDefinition相对于ChildBeanDefinition更灵活,GenericBeanDefinition不需要强制指定parentName

关于BeanBeanDefinition的区别,就说到这,最后再次重申本文章的内容:本文主要以分析Spring源码模块脉络为主,主要带领读者理清Spring运行的流程和脉络,不会深究一些知识细节,避免陷入细节无法自拔,所以虽然BeanDefinition很重要,是Spring的基石,但还是以介绍为主,并不会深入进入分析源码,意在最快时间带领读者进入Spring的脉络与流程,如果对某个接口或者某个实现类的逻辑比较感兴趣,可以自行阅读对应的源码。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-06-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 系列文章概述
    • IoC与容器
      • Bean和BeanDefinition
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档