如何理解 Spring 的 IOC 思想?

前言

一说起 Spring 大家都知道 Spring 有两个思想,即 IOC 和 AOP,AOP 比较容易理解,但 IOC 却在我学习 Spring 很长一段时间之后才算理解,故在此记录下来,供其他学习者参考。

是什么

IOC 全称是 Inversion of Control ,是一种叫做 控制反转 的设计思想。
与之关联的是 DI 全称 Dependency Injection,即 依赖注入,IOC 容器通过 DI 来实现控制反转。

ps: 我知道你们也不想看这些总结性的概念,来看个例子吧。

为什么

那为什么需要用到 IOC 呢?先来看看我们之前是怎么写代码的。

例如在一个 Person 类中需要一个 A 类的对象,调用 A 类的方法来完成工作。

1
2
3
4
5
6
public class Person {
A a = new A();
public void work() {
a.xxx();
}
}

然后有一天出现了一个 B 类,B 类可以实现同样的功能,且效率更高。于是你改起了代码:

1
2
3
4
5
6
public class Person {
B b = new B();
public void work() {
b.xxx();
}
}

我们来看这样的方式,是不是有些死板呢,需要改的地方很多,如果 100 个类中都调用了这个类,那修改的工作量未免也太大了。

这时其实可以将 A 和 B 之间的特型抽象出一个接口出来,叫 S。
让 A 和 B 都实现 S 接口,

那么现在的代码就成这样了:

1
2
3
4
5
6
public class Person {
S s = new A();
public void work() {
s.xxx();
}
}

这时,如果我们如果想换成 B 类,只需要改很少的代码:

1
2
3
4
5
6
public class Person {
S s = new B();
public void work() {
s.xxx();
}
}

那么这样还有一个问题,就是如果 A 或 B 类需要设置一些参数,那么怎么办,再修改代码?那样耦合性还是太高了。

怎么做

这是就用到了 IOC,将所有的对象,交由 Spring 容器来管理,只需要在 Spring 的配置文件里修改到底需要哪个类即可。

1
2
3
4
5
6
public class Person {
S s;
public void work() {
s.xxx();
}
}
1
2
3
4
5
6
7
<!--约束和一些配置略-->
<bean id="A" class="package.A">
<bean id="B" class="package.B">
<bean id="person" class="package.Person">
<property name="S" ref="A"/>
<!-- 或 <property name="S" ref="B"/> -->
</bean>

如此就进行了进一步的解耦,其实完全可以把 Person 当作工作中的项目的 Service 类,而 A 和 B 是两个不同数据库的实现,或客户从 A 需求改到 B 需求,如此可以方便的维护我们的代码。

  • 本文作者: 赵俊
  • 本文链接: http://www.zhaojun.im/spring-ioc/
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!