IOC 理论
- Ioc全称为 Inversion of control,直译为:控制反转,就是,你不用来找我们,我们会去找你的.
- 两种实现: 依赖查找 DL 和 依赖注入 DI
- DL 已经被抛弃,因为需要用户自己去使用API进行查找资源和组装对象,侵入性的
- DI 是spring 使用的方式,容器负责组件的装配.
- Spring IOC 就是由Spring IOC容器来负责对象生命周期和对象之间的关系
该怎么理解 控制反转 呢?
- 谁控制谁
- 控制什么
- 为何是反转
- 哪些方面反转了
举个例子
以前我们在家不想做饭了,就出去吃,这样一个过程就是,我们要找到一个饭店,然后自己去买,做好的饭菜,吃什么得自己一个个去买,
是我们主动去让别人为我们服务;
那么现在呢,有了IOC帮我们,我们需要啥,只要在统一的外卖平台,让别人送对应的东西过来,至于店在哪里,我们根本都不关心,我们只需要,吃这个饭菜而已.
所以 IoC 就是这么简单!原来是需要什么东西自己去拿,现在是需要什么东西让别人(IOC Service Provider)送过来
好的现在来回答问题
- 谁控制谁:在传统的 开发模式下,我们都采用直接new一个对象的方式来创建对象,也就是说你依赖的对象直接由你自己控制,但是有了IOC容器之后,则直接由IOC容器来控制.所以谁控制谁,当然是IOC容器控制对象了.
- 控制什么:控制对象的生命周期
- 为何是反转:没有IOC的时候我们都是在自己对象中去主动创建被依赖的对象,这是正转,但是有了IOC之后,所依赖的对象直接由IOC容器创建后,注入到被注入的对象中,依赖的对象由原来的主动获取变成被动接受,所以是反转.
- 哪些方面反转了:所依赖对象的获取被反转了
容器
对于 IoC 来说,最重要的就是容器。容器管理着 Bean 的生命周期,控制着 Bean 的依赖注入。
那么, Spring 如何设计容器的呢?
Spring 作者 Rod Johnson 设计了两个接口用以表示容器。
- BeanFactory
- ApplicationContext
BeanFactory 粗暴简单,可以理解为就是个 HashMap,Key 是 BeanName,Value 是 Bean 实例。通常只提供注册(put),获取(get)这两个功能。我们可以称之为 “低级容器”。
ApplicationContext 可以称之为 “高级容器”。因为他比 BeanFactory 多了更多的功能。他继承了多个接口。因此具备了更多的功能。例如资源的获取,支持多种消息(例如 JSP tag 的支持),对 BeanFactory 多了工具级别的支持等待。所以你看他的名字,已经不是 BeanFactory 之类的工厂了,而是 “应用上下文”, 代表着整个大容器的所有功能。该接口定义了一个 refresh 方法,此方法是所有阅读 Spring 源码的人的最熟悉的方法,用于刷新整个容器,即重新加载/刷新所有的 bean。
当然,除了这两个大接口,还有其他的辅助接口,但我今天不会花太多篇幅介绍他们。
为了更直观的展示 “低级容器” 和 “高级容器” 的关系,我这里通过常用的 ClassPathXmlApplicationContext 类,来展示整个容器的层级 UML 关系。
IoC 在 Spring 里,只需要低级容器就可以实现,2 个步骤:
a. 加载配置文件,解析成 BeanDefinition 放在 Map 里。
b. 调用 getBean 的时候,从 BeanDefinition 所属的 Map 里,拿出 Class 对象进行实例化,同时,如果有依赖关系,将递归调用 getBean 方法 —— 完成依赖注入。
上面就是 Spring 低级容器(BeanFactory)的 IoC。
至于高级容器 ApplicationContext,他包含了低级容器的功能,当他执行 refresh 模板方法的时候,将刷新整个容器的 Bean。同时其作为高级容器,包含了太多的功能。一句话,他不仅仅是 IoC。他支持不同信息源头,支持 BeanFactory 工具类,支持层级容器,支持访问文件资源,支持事件发布通知,支持接口回调等等。
网友评论