《spring如此简单》第二节--IOC思想的实现,容器是什么

如果你想不费太多脑筋认识spring,你只需要记住,spring=IOC+AOP就好,其他的都是附带的工程化优化。

为什么我们需要IOC,上一节已经讲过了 juejin.cn/post/764125...

如果只能给我一句话,来说明spring是如何实现IOC的,我会回答:

框架创建一个对象,专用于管理业务中的组件。

所谓的组件,就是进行业务工作的对象,例如我们的controller,service这些bean。

而这个管理者对象,就是我们所说的容器

而所谓的管理工作,就是创建对象,实现依赖关系,操作组件的生命周期。

容器原始接口BeanFactory

BeanFactory是一个接口,它定义了容器的本源工作,也是最高层级的接口。

arduino 复制代码
public interface BeanFactory 
{ 
    // 根据名称拿Bean 
    Object getBean(String name); 
    // 根据名称+类型拿Bean <T> 
    T getBean(String name, Class<T> requiredType); 
    // 判断是否存在
    Bean boolean containsBean(String name); 
    // 判断是否单例 
    boolean isSingleton(String name); 
}

可以看到,根源的容器接口,主要做的,就是获取bean。

这也描绘了它的主要使命------解耦,容器的本质功能,就是1把bean传递给需要的人,而不是对象们自行创建和寻找bean。

但是,光获取bean的功能是远远不够的。bean的实例化,依赖注入,生命周期,肯定也需要实现,于是乎,一层层的抽象出来了。

最开始的时候,我们使用的是XmlBeanFactory这个实现类。

它是经过了一系列的功能扩充。

复制代码
接口继承链
BeanFactory 
├─HierarchicalBeanFactory 父子容器规范 
├─ListableBeanFactory 批量查询规范 
└─AutowireCapableBeanFactory 装配生命周期规范 
↓ ConfigurableBeanFactory 可配置规范 
↓ ConfigurableListableBeanFactory 集齐所有BeanFactory规范

类继承链
DefaultSingletonBeanRegistry 单例缓存实现 
↓ FactoryBeanRegistrySupport FactoryBean处理实现
↓ AbstractBeanFactory 实现BeanFactory基础逻辑
↓ AbstractAutowireCapableBeanFactory 实现创建+注入+生命周期 
↓ DefaultListableBeanFactory 实现BeanDefinition注册+全能力落地 
↓ XmlBeanFactory 继承所有底层实现,再加XML解析

XmlBeanFactory的核心功能便是加载XML 配置,把标签转化为内存中的bean。并且继承父类能力,管理bean的生命周期。

  • 单例 Bean 缓存
  • 依赖注入
  • Bean 实例创建
  • 三级缓存解决循环依赖
  • Bean 别名、作用域管理

而它早已被淘汰,也不是当今我们的主角。

容器的进化ApplicationContext

在框架的工作中,渐渐发现许多的工作常用,但是XmlBeanFactory却处理不了,例如

  • 容器事件发布
  • 国际化 i18n
  • 统一资源加载
  • 环境变量配置
  • 不会自动执行 BeanPostProcessor
  • 不支持预加载 Bean,错误发现晚
  • 不整合 AOP、事务等企业级功能

而这一切,在ApplicationContext中实现了。

javascript 复制代码
ApplicationContext (org.springframework.context)
├─ EnvironmentCapable
│  └─ 核心能力:获取/管理环境配置(配置文件、系统变量、profile)
│
├─ ListableBeanFactory
│  ├─ BeanFactory
│  │  └─ 核心能力:最基础的IoC容器规范(getBean、判断单例/存在)
│  └─ 核心能力:批量获取Bean、按类型/注解查询Bean、获取Bean定义元数据
│
├─ HierarchicalBeanFactory
│  ├─ BeanFactory
│  │  └─ 核心能力:同上
│  └─ 核心能力:支持父子容器层级结构、区分本地/父容器Bean
│
├─ MessageSource
│  └─ 核心能力:国际化消息支持(多语言文本)
│
├─ ApplicationEventPublisher
│  └─ 核心能力:容器事件发布(如容器启动、刷新事件)
│
└─ ResourcePatternResolver
   ├─ ResourceLoader
   │  └─ 核心能力:统一资源加载(classpath:/、file:/等协议)
   └─ 核心能力:支持Ant风格路径匹配的资源批量加载

根据继承图,我们可以看到,这个接口有多么强大的功能,在普通的IOC管理之外,还有一系列的工程能力,例如国际化,统一资源加载,环境配置等等。

而我们平时常用的springboot项目,其容器也是这个接口的间接实现类------AnnotationConfigServletWebServerApplicationContext

说它间接,是因为中间又隔了很多层的继承。

但是为什么我们平时聊得更多的是ApplicationContext而不是AnnotationConfigServletWebServerApplicationContext呢?

因为ApplicationContext这个层面,已经定义好了所有容器需要对外的能力,到达这个层次,容器就齐活儿了。

而更多的继承,本质是扩展更多的细节功能,或者特殊场景(例如无 Web 环境GenericApplicationContext)。

我们可以看到,容器的继承关系,是学习面向对象的"继承"思想的典型案例

spring框架的价值,绝大部分就在ApplicationConetxt这个容器身上了,要搞懂spring,只需要去挖掘它即可。

容器的根基功能就是:

  1. IoC 控制反转。把对象创建、依赖管理全部交给容器,程序员不用 new 对象,彻底解耦。
  2. DI 依赖注入。容器自动装配属性、自动维护依赖关系,解决项目最头疼的对象耦合问题。
  3. 容器统一托管全组件。所有 @Controller / @Service / @Mapper / @Component 全由容器统一初始化、管理生命周期。

目前spring已经借助容器帮我们实现了业务代码的解耦,其余的所有功能AOP、事务、配置环境、事件监听、整合三方插件,全部都依赖于IOC的根基。

那么,容器具体是如何将这些业务对象,转换为乖巧的bean,并且治理得有模有样的?下一节,我们来解析,bean,在spring框架中,到底是个什么样的存在,以及它是如何参与到框架工作,它身上又有哪些可以挖掘的地方(非常重要!)。

相关推荐
GetcharZp2 小时前
深入浅出 etcd:从 K8s 灵魂到 Golang 实战,分布式系统的“定海神针”!
后端
hikktn3 小时前
企业级Spring Boot应用管理:从零打造生产级启动脚本
java·spring boot·后端
SimonKing3 小时前
别再死磕 Elasticsearch 了,这个轻量级搜索引擎更香
java·后端·程序员
Gopher_HBo3 小时前
阻塞队列之ArrayBlockingQueue
后端
AI人工智能+电脑小能手3 小时前
【大白话说Java面试题 第64题】【JVM篇】第24题:强引用、软引用、弱引用、虚引用分别是什么?
java·开发语言·jvm·面试
怕浪猫3 小时前
小厂三年我现在怎么样了
后端·面试
无风听海3 小时前
深入理解 ASP.NET Core 中的 IActionResult
后端·asp.net
霸道流氓气质3 小时前
Spring Boot + MyBatis-Plus 实现异常隔离的 Upsert 数据落库(含远程调用数据补全)
spring boot·后端·mybatis