什么是IoC?

控制反转是软件工程中的一项原则,它将对象或者程序的部分控制权转移到容器或框架上。我们最常在面向对象编程的上下文中使用它。

与我们自定义代码调用库的传统编程相比,IoC使框架能够控制程序流并调用我们的自定义代码。为了实现这一点,框架使用了带有附加行为的抽象。如果我们想添加我们自己的行为,我们需要扩展框架的类或插入我们自己的类。

IoC的优点是:

  • 将任务的执行与其实现分离
  • 更容易在不同的实现之间切换
  • 程序的模块化程度更高
  • 通过隔离组件或者模拟其依赖项,并允许组件通过协议进行通信,从而更轻松地测试程序

我们通过各种机制来实现控制反转,例如:策略设计模式、服务定位器模式、工厂模式和依赖注入(DI)。

什么是DI?

依赖注入是一种我们可以用来实现IOC的模式,其中被反转的控制是设置对象的依赖关系。将对象与其他对象联系,或将对象“注入”到其他对象中。

传统的编程中船舰对象依赖是这样的:

在上面的示例中,我们需要在Todo类本身中实例化Item接口的实现。

而通过使用DI,它是这样的:

通过使用DI,我们无需指定我们想要的Item的实现。

接下来我们将演示如何通过注解提供Item的实现。

Spring IoC容器

在Spring中,接口ApplicationContext表示IoC容器。Spring容器负责实例化、配置和组装成为bean的对象,以及管理他们的生命周期。

Spring提供了ApplicationContext接口的几种实现:ClassPathXmlApplicationContext和FileSystemXmlApplicationContext用于独立的应用程序,以及WebApplicationContext用于Web应用程序。

为了组装bean,容器使用配置元数据,可以是XML配置或者注解的形式。

这是手动实例化容器的一种方式:

要在上面的示例中设置Item的属性,我们可以使用元数据。然后容器将读取此元数据并在运行时使用它来组装bean。

Spring的依赖注入可以通过构造函数、setter或属性来完成。

基于构造函数注入

基于Setter注入

基于对象属性注入

相对于其他两种方式,这种方式可能看起来更简单、更干净,但是不建议使用它,因为它有一些缺点,例如:

  • 此方法使用反射来注入依赖项,这比基于构造函数或基于setter的注入成本高

如果我们想代码看起来简单干净可以是用Lombok的@RequiredArgsConstructor和@NonNull来实现构造函数注入:

可以在 Martin Fowler 的文章或Spring官网中阅读更多关于这些概念的信息:

  • 控制容器反转和依赖注入模式 https://martinfowler.com/articles/injection.html
  • 控制反转 https://martinfowler.com/bliki/InversionOfControl.html
  • Spring 框架参考文档 https://docs.spring.io/spring-framework/docs/current/reference/html/#beans-dependencies

发表回复

后才能评论