原理
IoC全称Inversion of Control,直译为控制反转.
首先是一个常见的场景,比如我们一共有三个类: BookService, UserService, HistoryService
这三个类都需要执行以下操作
- 初始化数据库连接
- 查询数据
- 返回数据
这就带来了问题,
- 实例化一个类的时候会带来冗余的代码,比如初始化数据库连接 。
- 组件里面依赖的资源需要进行销毁? 但是这个组件可能又被其他组件依赖,这样依赖很容易出现资源无法销毁的情况
- 一个组件里面,实例化太多的组件,依赖关系复杂,不好测试,容易出错
解决方法:
把这些组件的创建,交给系统管理,而不是在类里面实例化组件,而是统一由系统创建,最后由系统销毁
如何做?
- Spring里面的 IOC 负责创建组件
- IOC 负责根据依赖关系组装组件
- IOC 负责销毁和关闭资源
一般有两种方法,一个是通过 set* 方法注入,一个是通过构造函数注入
比如一个查询书籍的 service,首先我们需要依赖数据库,那么我们就注入数据库实例
public class BookService {private DataSource dataSource;public void setDataSource(DataSource dataSource) {this.dataSource = dataSource;}}
这个程序不会自己去实例化数据库连接实例,而是通过 setDataBaseSource 把数据库实例给传进来。它解决了一个最主要的问题:将组件的创建+配置与组件的使用相分离,并且,由IoC容器负责管理组件的生命周期。
然后在 XML 中, 我们声明这个依赖关系。
<beans><bean id="dataSource" class="HikariDataSource" /><bean id="bookService" class="BookService"><property name="dataSource" ref="dataSource" /></bean><bean id="userService" class="UserService"><property name="dataSource" ref="dataSource" /></bean></beans>
然后 IOC 会根据这个 XML 进行装配,用 Java 代码写出来像这样
DataSource dataSource = new DataSource();
BookService bookService = new BookService();
bookService.setDataSource(dataSource);
只不过 spring 中是通过反射来完成的
另一种方法是通过构造方法进行注入:
public class BookService {
private DataSource dataSource;
public BookService(DataSource dataSource) {
this.dataSource = dataSource;
}
}

