当前位置: 代码迷 >> 综合 >> Spring IoC的理解
  详细解决方案

Spring IoC的理解

热度:61   发布时间:2024-02-23 11:25:34.0

1. What 什么是IoC

IoC全称Inversion of Control,直译为控制反转。

2. Why 为什么使用

我们假定一个在线书店,通过BookService获取书籍:

public class BookService {private HikariConfig config = new HikariConfig();private DataSource dataSource = new HikariDataSource(config);public Book getBook(long bookId) {try (Connection conn = dataSource.getConnection()) {...return book;}}
}

为了从数据库查询书籍,BookService持有一个DataSource。为了实例化一个HikariDataSource,又不得不实例化一个HikariConfig。

从上面的例子可以看出,如果一个系统有大量的组件,其生命周期和相互之间的依赖关系如果由组件自身来维护,不但大大增加了系统的复杂度,而且会导致组件之间极为紧密的耦合,继而给测试和维护带来了极大的困难。

因此,核心问题是:

  1. 谁负责创建组件?
  2. 谁负责根据依赖关系组装组件?
  3. 销毁时,如何按依赖顺序正确销毁?

解决这一问题的核心方案就是IoC。

3. HOW 怎么实现

在IoC模式下,控制权发生了反转,即从应用程序转移到了IoC容器,所有组件不再由应用程序自己创建和配置,而是由IoC容器负责,这样,应用程序只需要直接使用已经创建好并且配置好的组件。为了能让组件在IoC容器中被“装配”出来,需要某种“注入”机制,例如,BookService自己并不会创建DataSource,而是等待外部通过setDataSource()方法来注入一个DataSource:

public class BookService {private DataSource dataSource;public void setDataSource(DataSource dataSource) {this.dataSource = dataSource;}
}

在正常情况下,我们有两种方式实现依赖注入,1、使用构造方法;2、使用 Setter() 方法。一般使用构造方法(因为依赖可能有多个):

因为 Spring 实现了依赖注入,所以我们程序员没有了创建对象的控制权,所以也被称为控制反转(Inversion of Control,简称 IoC)。因为 Spring 使用 Map 管理 BeanDefinition,我们也可以将 Spring 称为 IoC 容器。

在业务开发中,如果每个业务类均设置构造函数,并且需要在 xml 中配置,那么就太繁琐,还容易出错。Spring 从 2.5ref 开始,新增了注解,可以使用注解来替代业务类的 xml 配置和构造函数。

  • 使用 @Component 注解代替 <bean>
  • 使用 @Autowired 注解代替 <constructor-arg> + 构造函数。
@Component
public class BookService {@Autowiredprivate DataSource dataSource;
}

Spring 的原理离不开两个关键词:反射和注解。

  • 反射:在创建 Bean 实例和依赖注入是都需要使用反射。
  • 注解:使用注解可大大提升代码可阅读性,降低复杂度。注解本质上是作为一个标识,获取注解时需要使用字节码技术。

现在我们一般很少使用 xml 来设置 bean,但了解了 xml 可以更好的理解 Spring 注解的原理。

 

  • @Component 作为组件标识,代表需要 Spring 管理
  • @Autowired 用于判断是否需要依赖注入,代替构造函数
  • @ComponentScan 指定组件扫描路径,不指定即为当前路径
  • @Configuration 代表配置类,作为 Spring 寻找需要被管理 Bean 的入口
  • @Bean 实现将任意 Bean 注入容器
  • @EnableAutoConfiguration 实现自动加载配置类到容器
  相关解决方案