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容器配置依赖对象。IoCDI是同一个概念的不同角度描述。

DL

依赖查找

DL(Dependency Lookup)依赖查找:当前实体主动去容器中查找其依赖的服务。
通过getBean("beanName");getBean(XxxService.class);来主动查找取出容器中的Bean

1
2
3
4
5
6
7
8
9
10
public class Application {

public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
//主动查找需要依赖的Bean
// UserService userService = (UserService) context.getBean("userServiceImpl");
UserServiceImpl userService = context.getBean(UserServiceImpl.class);
userService.doSomethings();
}
}

Spring IoC容器

Spring IoC容器是内核、AOP、声明式事务等核心功能的基础。是负责控制对象生命周期和对象之间的关系,完成类的初始化和装配,让开发者专注于更有意义的业务逻辑的开发。

Spring 通过配置文件或注解描述类和类之间的依赖关系,自动完成初始化和依赖工作。

作者

光星

发布于

2018-05-05

更新于

2022-06-17

许可协议

评论