【Spring IOC容器学习笔记】一——什么是Spring IOC容器,它是怎么工作的

摘要

Spring IOC容器是Spring的核心功能,它构成了Spring框架的骨骼结构,没有它就没有上层MVC、AOP等高级特性。这节的学习笔记主要回答下面几个问题:

  • Spring IOC容器是用来做什么的?
  • 什么是bean?
  • Spring IOC容器是如何工作的?
  • Spring IOC容器与BeanFactory和ApplicationContext的关系是什么?

1 Spring IOC容器与bean

1.1 什么是Spring IOC 容器

在这里插入图片描述
把Spring IOC 容器看做一个黑盒,它的功能就是根据读取的配置元数据,将应用中的业务对象(POJOs)实例化后建立互相之间的依赖关系,提供给我们一个可使用的系统。

1.2 什么是bean

每个业务对象,经过容器的实例化得到的就是bean。bean被容器管理相互间的依赖关系,组成应用。在我的另一篇学习笔记里有bean的详细介绍,这里就不展开了。

1.3 怎么理解IOC

IOC是Inverse of Controll的简写,翻译为控制反转,指的是被实例化的对象对依赖创建的控制权从自身转移到容器。IOC的概念比较晦涩,我们可以借助依赖注入(Dependency Injection,DI)的概念辅助理解它。依赖注入的过程是指,POJO被容器实例化后,由容器负责将它的依赖准备好供使用。关于依赖的更详细说明可以看另外一篇学习笔记

IOC技术与直接通过new 方法创建依赖相比有什么优点?

  • 代码更加简洁
  • 实现了依赖的创建和使用的解耦(使用依赖的类不用再关心去哪里找依赖去创建)
  • 更容易进行单元测试

2 Spring IOC容器工作原理

这部分,我们进入Spring IOC 内部,看它由哪些组件构成,是怎么工作的。
容器中的每一个bean都会有一个对应的BeanDefinition实例,该实例负责保存bean对象的所有必要信息,包括bean对象的class类型、是否是抽象类、构造方法和参数、其它属性等等。当客户端向容器请求相应对象时,容器就会通过这些信息准备一个完整可用的bean实例返回给客户端。
BeanDefinitionRegistry抽象了bean的注册逻辑,包含registerBeanDefinition()、removeBeanDefinition()、getBeanDefinition()等注册管理BeanDefinition的方法。
BeanFactory抽象了bean的管理逻辑,包含getBean、containBean、getType、getAliases等管理bean的方法。
他们的关系如下图:
在这里插入图片描述
Spring IOC 容器的工作流程大致分为两个阶段:

阶段1:容器启动

容器在这阶段的主要工作是收集bean信息,也会进行一些验证性和辅助性的工作。容器要加载Configuration Meta信息,除了纯java代码实现配置的情况,其他方式如通过XML文件的读取,需要借助BeanDefinitionReader组件进行解析。BeanDefinitionReader读取和分析Configuration Meta信息后,组装信息为bean对应的BeanDefinition,并把它注册到BeanDefinitonRegistry中,就完成了容器启动。示例代码:

// 通常为BeanDefinitionRegistry的实现类,这里以DeFaultListabeBeanFactory为例
BeanDefinitionRegistry beanRegistry = new DefaultListableBeanFactory(); 
// XmlBeanDefinitionReader实现了BeanDefinitionReader接口,用于解析XML文件
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReaderImpl(beanRegistry);
// 加载配置文件
beanDefinitionReader.loadBeanDefinitions("classpath:spring-bean.xml");

阶段2:实例加载

经过阶段1后,当某个请求通过容器的getBean方法请求某个对象,或者因为依赖关系容器需要隐式的调用getBean时,就会触发阶段2的工作:容器会首先检查所请求的对象之前是否已经实例化完成。如果没有,则会根据注册的BeanDefinition所提供的信息实例化被请求对象,并为其注入依赖。当该对象装配完毕后,容器会立即将其返回给请求方法使用。

// 从容器中获取bean实例
BeanFactory container = (BeanFactory)beanRegistry;
Business business = (Business)container.getBean("beanName");

3 BeanFactory和ApplicationContext

BeanFactory可以管理任何对象,它是Spring IOC容器一种简单的实现,提供了最基本的依赖注入(DI)支持。而在实际场景下,我们更多的使用另外一种类型的容器:ApplicationContext,它集成自BeanFactory,除了基本DI功能,还提供了更高级的功能,如事件监听。
两者bean实例加载策略有区别:BeanFactory默认是延迟加载策略,即只有当访问容器中的某个对象时,才对该对象进行实例化和依赖注入操作;ApplicationContext则模式在容器启动时就全部完成实例化和依赖注入操作。

总结

对使用者来说,可以把spring 容器看做一个生产工厂,它提前根据生产说明(Configuration Meta)把物料(POJOs)加工成产品(beans),使用者只要报出需要的产品名字(beanName)就可以得到提前生产好的产品,整体是简单工厂模式的体现。
容器的实现可以是简单的BeanFactory或更高级的ApplicationContext。它们借助BeanDefiniton组件实现对bean及依赖信息的管理, 容器启动时收集所有bean的信息。当实例化bean的时候,容器负责将其依赖对象也进行实例化以供使用,这个过程就是依赖注入。

参考资料

1,给你一份Spring Boot知识清单
2,Spring Core Technologies

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值