Spring(十八):Spring IoC/DI 理解
IoC(Inverse of Control)
控制反转:不是某种技术,而是一种设计思想,Spring IoC容器是该设计思想的实现。
控制反转包含两层意思,一是控制,二是反转。
DI(Dependency Injection)
依赖注入:是组件之间、对象之间的依赖关系由容器在运行期决定,即由容器动态的将某个依赖对象注入到组件中。
控制反转和依赖注入实际说的是同一件事,只是站在两个对立的角度来解释这件事。控制反转是站在调用者的角度来理解,本来由我自己来创建对象的,现在不需要这么做了,由容器直接给你所需要的;依赖注入是站在容器的角度来理解,你需要什么,我找到给你就是,你没必要自己创建了。
IoC
控制反转
控制:指的是有控制权,要明确谁控制谁,控制什么。
反转:指移除控制权,转交给第三方决定。对于软件开发,即设计好的对象的控制权从调用类中移除,即由Spring容器借由Bean
配置来控制。
- 谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过
new
进行创建对象,是程序主动去创建依赖对象;而IoC
是有专门一个容器来创建这些对象,即由Ioc
容器来控制对象的创建;谁控制谁?当然是IoC
容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。 - 为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。
IoC作用
IoC
思想可以指导我们设计出低耦合的程序。传统的应用由类内部主动创建依赖对象,导致了类与类之间的高耦合;使用IoC
容器,把创建和查找依赖对象的控制权交给了容器,由容器进行注入依赖对象,这样对象与对象之间是低耦合的。
其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。
IoC容器的依赖注入流程可以分两个阶段,第一个阶段是收集和注册,将 Bean 扫描并注册到容器中;第二个阶段是分析和组装,分析 Bean 之间的依赖关系,然后根据它们之间的依赖关系组装它们。
DI
DI(Dependency Injection)
依赖注入:当前实体被动地接受其依赖的其他组件IoC容器注入。
依赖注入
理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:
- 谁依赖于谁:当然是应用程序依赖于
IoC
容器。 - 为什么需要依赖:应用程序需要
IoC
容器来提供对象需要的外部资源。 - 谁注入谁:很明显是
IoC
容器注入应用程序某个对象,应用程序依赖的对象。 - 注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)。
DI作用
依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
由于IoC理解起来比较晦涩(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),最终软件界的泰斗级人物Martin Fowler提出了DI(Dependency Injection, 依赖注入)
,相对IoC 而言,依赖注入明确描述了 被注入对象依赖IoC容器配置依赖对象。IoC和DI是同一个概念的不同角度描述。
DL
依赖查找
DL(Dependency Lookup)
依赖查找:当前实体主动去容器中查找其依赖的服务。
通过getBean("beanName");
或getBean(XxxService.class);
来主动查找取出容器中的Bean
。
1 | public class Application { |
Spring IoC容器
Spring IoC容器是内核、AOP、声明式事务等核心功能的基础。是负责控制对象生命周期和对象之间的关系,完成类的初始化和装配,让开发者专注于更有意义的业务逻辑的开发。
Spring 通过配置文件或注解描述类和类之间的依赖关系,自动完成初始化和依赖工作。
Spring(十八):Spring IoC/DI 理解