对Spring IOC的理解

对Spring IOC的理解

1. IOC是什么

Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。

用图例说明一下,传统程序设计如图1-1,都是主动去创建相关对象然后再组合起来:
 

对Spring IOC的理解
图1-1 传统应用程序示意图

当有了IoC/DI的容器后,在客户端类中不再主动去创建这些对象了,如图1-2所示:
 

对Spring IOC的理解
图1-2 有IoC/DI容器后程序结构示意图

所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。

要用IOC容器创建对象通常需要以下操作:

  • 在applicationContext.xml中定义的bean
  • 用@Controller @Service @Component @Respository等注解标注某一个类1

IOC容器是一种设计思想,一旦你选择了使用IOC容器,那么它应该贯穿于整个项目工程中。假设Apple类中有一个属性

@Autowired
 private Size size;

Apple类的实例依赖于IOC容器中的size对象,你的Apple实例不是从IOC容器中获取的,而是手动new的一个Apple apple= new Apple();此时,apple实例中的size属性会是null,这也是新手常犯的一个错误。一旦你的项目用IOC容器管理对象,那么就一直使用IOC,否则会导致对象依赖关系混乱而让你的同事无法适从。

2. 控制反转?依赖注入?

在上述实例中,

@Autowired
 private Size size;

这就向Apple类中注入了Size实例,这种方式叫做DI,即依赖注入,So,依赖注入也是IOC容器干的,总之依赖注入应该算作为整个IOC容器管理的一部分,因此你大可不必纠结IOC和DI这两个名词的细节含义,不必非要做一个区分,因为他们们本质视为同一个目标服务的。

3. 小结

“不要给我们打电话,我们会打给你的(don’t call us, we’ll call you)”这是著名的好莱坞原则。

在好莱坞,把简历递交给演艺公司后就只有回家等待。由演艺公司对整个娱乐项目完全控制,演员只能被动式的接受公司的差使,在需要的环节中,完成自己的演出。

这和软件开发有一定的相似性, 演员们就像一个个Java Object, 最早的时候自己去创建自己所依赖的对象, 有了演艺公司(Spring容器)的介入,所有的依赖关系都是演艺公司搞定的, 于是控制就翻转了。

[参考]
[1]: https://www.cnblogs.com/xdp-gacl/p/4249939.html
[2]: 码农翻身微信公众号


  1. 简洁起见本文所有示例采用注解方式。 ↩︎