深入理解 Spring IoC 和 DI:掌握控制反转和依赖注入的精髓

这篇具有很好参考价值的文章主要介绍了深入理解 Spring IoC 和 DI:掌握控制反转和依赖注入的精髓。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在本文中,我们将介绍 IoC(控制反转)和 DI(依赖注入)的概念,以及如何在 Spring 框架中实现它们。

什么是控制反转?

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

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

这种架构的优点是:

  • 将任务的执行与其实现分离
  • 更容易在不同实现之间切换
  • 程序的更高的模块化
  • 更容易通过隔离组件或模拟其依赖项来测试程序,并允许组件通过契约进行通信

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

什么是依赖注入?

依赖注入是一种我们可以用来实现 IoC 的模式,其中被反转的控制是设置对象的依赖项。

将对象与其他对象连接或将对象“注入”到其他对象中是由汇编程序而不是对象本身完成的。

下面是在传统编程中创建对象依赖关系的方法:

public class Store {
    private Item item;

    public Store() {
        item = new ItemImpl1();
    }
}

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

通过使用 DI,我们可以重写该示例,而不指定我们想要的 Item 的实现:

public class Store {
    private Item item;

    public Store(Item item) {
        this.item = item;
    }
}

在接下来的几节中,我们将看看如何通过元数据提供 Item 的实现。

IoCDI 都是简单的概念,但它们对我们构建系统的方式有深刻的影响,因此值得充分理解。

Spring IoC容器

IoC 容器是实现 IoC 的框架的常见特征。

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

Spring 框架提供了 ApplicationContext 接口的几个实现:ClassPathXmlApplicationContextFileSystemXmlApplicationContext 用于独立应用程序,以及 WebApplicationContext 用于 Web 应用程序。

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

以下是手动实例化容器的一种方法:

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

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

Spring 中,可以通过构造函数、setter 或字段来进行依赖注入。

基于构造函数的依赖注入

在基于构造函数的依赖注入的情况下,容器将调用具有表示我们要设置的依赖项的参数的构造函数。

Spring 通过类型解决每个参数,然后按属性名称和索引进行消歧。让我们看看使用注释配置 bean 及其依赖项的配置:

@Configuration
public class AppConfig {

    @Bean
    public Item item1() {
        return new ItemImpl1();
    }

    @Bean
    public Store store() {
        return new Store(item1());
    }
}

@Configuration 注释表示该类是 bean 定义的源。我们也可以将其添加到多个配置类中。

我们在方法上使用 @Bean 注释来定义 bean。如果我们没有指定自定义名称,则 bean 名称将默认为方法名称。

对于默认的 singleton 范围的 beanSpring 首先检查是否已存在缓存的 bean 实例,仅在不存在时创建新实例。如果我们使用 prototype 范围,则容器为每个方法调用返回一个新的 bean 实例。

创建 bean 的另一种方式是通过 XML 配置:

<bean id="item1" class="org.baeldung.store.ItemImpl1" />
<bean id="store" class="org.baeldung.store.Store">
    <constructor-arg type="ItemImpl1" index="0" name="item" ref="item1" />
</bean>
## 基于setter的依赖注入

对于基于 `setter` 的 `DI`,容器将在调用没有参数的构造函数或没有参数的静态工厂方法来实例化 `bean` 之后调用我们类的 `setter` 方法。让我们使用注释创建此配置:

```java
@Bean
public Store store() {
    Store store = new Store();
    store.setItem(item1());
    return store;
}

我们也可以使用 XML 进行相同的 bean 配置:

<bean id="store" class="org.baeldung.store.Store">
    <property name="item" ref="item1" />
</bean>

我们可以将构造函数和 setter 类型的注入结合在同一个 bean 中。Spring 文档建议将基于构造函数的注入用于必需的依赖项,将基于 setter 的注入用于可选的依赖项。

基于字段的依赖注入

在基于字段的 DI 的情况下,我们可以通过带有 @Autowired 注释的注释将依赖项注入其中:

public class Store {
    @Autowired
    private Item item;
}

在构造 Store 对象时,如果没有构造函数或 setter 方法将 Item bean 注入其中,容器将使用反射将 Item 注入 Store 中。

我们也可以使用 XML 来实现这一点。

这种方法可能看起来更简单、更清晰,但我们不建议使用它,因为它有一些缺点,例如:

  • 此方法使用反射来注入依赖项,这比基于构造函数或 setter 的注入更昂贵。
  • 使用此方法很容易添加多个依赖项。如果我们使用构造函数注入,有多个参数会让我们认为这个类做了不止一件事,这可能违反单一责任原则。

自动装配依赖项

自动装配允许 Spring 容器通过检查已定义的 bean 来自动解决协作 bean 之间的依赖关系。

使用 XML 配置有四种自动装配 bean 的模式:

  • no:默认值 - 这意味着不使用自动装配,我们必须显式地命名依赖项。
  • byName:按属性名称进行自动装配,因此 Spring 将查找与需要设置的属性同名的 bean
  • byType:类似于按名称进行自动装配,仅基于属性的类型。这意味着 Spring 将查找具有相同类型的属性来设置的 bean。如果有多个 bean 具有该类型,则框架会抛出异常。
  • constructor:基于构造函数参数进行自动装配,意味着 Spring 将查找具有与构造函数参数相同类型的 bean

例如,让我们通过类型创建具有依赖项 itemstore bean

public class AppConfig {
    @Bean
    public Item item() {
        return new ItemImpl1();
    }

    @Bean(autowire = Autowire.BY_TYPE)
    public Store store() {
        return new Store();
    }
}

请注意,自 Spring 5.1 起,autowire 属性已弃用。

我们还可以使用 @Autowired 注释按类型注入 bean

public class Store {
    @Autowired
    private Item item;
}

如果存在相同类型的多个 bean,则可以使用 @Qualifier 注释按名称引用 bean

public class Store {
    @Autowired
    @Qualifier("item1")
    private Item item;
}

现在,让我们通过 XML 配置按类型自动装配 bean

<bean id="store" class="org.baeldung.store.Store" autowire="byType"> </bean>

接下来,让我们通过 XML 按名称将名为 itembean 注入到 store beanitem 属性中:

<bean id="item" class="org.baeldung.store.ItemImpl1" />

<bean id="store" class="org.baeldung.store.Store" autowire="byName">
</bean>

我们还可以通过构造函数参数或 setter 显式定义依赖关系来覆盖自动装配。

惰性初始化的bean

默认情况下,容器在初始化期间创建和配置所有单例 bean。为了避免这种情况,我们可以在 bean 配置上使用值为 truelazy-init 属性:

<bean id="item1" class="org.baeldung.store.ItemImpl1" lazy-init="true" />

因此,只有在第一次请求它时,才会初始化 item1 bean,而不是在启动时。这样做的优点是初始化时间更快,但缺点是我们在 bean 被请求之后才会发现任何配置错误,这可能是应用程序已运行数小时甚至数天之后。

结论

在本文中,我们介绍了控制反转和依赖注入的概念,并在 Spring 框架中进行了示例。

最后

为了方便其他设备和平台的小伙伴观看往期文章:

微信公众号搜索:Let us Coding,关注后即可获取最新文章推送

看完如果觉得有帮助,欢迎 点赞、收藏、关注文章来源地址https://www.toymoban.com/news/detail-760538.html

到了这里,关于深入理解 Spring IoC 和 DI:掌握控制反转和依赖注入的精髓的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java Spring IoC&DI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性

    💓 博客主页:从零开始的-CodeNinja之路 ⏩ 收录文章:Java Spring IoCDI :探索Java Spring中控制反转和依赖注入的威力,增强灵活性和可维护性 🎉欢迎大家点赞👍评论📝收藏⭐文章 我们一下要学习的内容都是为了实现⾼内聚低耦合来进行的 软件设计原则:⾼内聚低耦合. ⾼内聚指

    2024年04月15日
    浏览(47)
  • 深入理解WPF中的依赖注入和控制反转

    在WPF开发中, 依赖注入(Dependency Injection)和控制反转(Inversion of Control)是程序解耦的关键,在当今软件工程中占有举足轻重的地位,两者之间有着密不可分的联系 。今天就以一个简单的小例子,简述如何在WPF中实现依赖注入和控制反转,仅供学习分享使用,如有不足之处

    2024年02月06日
    浏览(52)
  • Spring-2-深入理解Spring 注解依赖注入(DI):简化Java应用程序开发

      掌握纯注解开发依赖注入(DI)模式 学习使用纯注解进行第三方Bean注入 问题导入 思考:如何使用注解方式将Bean对象注入到类中 1.1 使用@Autowired注解开启自动装配模式(按类型) 说明:不管是使用配置文件还是配置类,都必须进行对应的Spring注解包扫描才可以使用。@Autowired默

    2024年02月14日
    浏览(58)
  • 【Spring教程十】Spring框架实战:全面深入详解IOC/DI之--纯注解开发模式下的依赖注入&&注解读取properties配置文件

    欢迎大家回到《 Java教程之Spring30天快速入门》,本教程所有示例均基于Maven实现,如果您对Maven还很陌生,请移步本人的博文《 如何在windows11下安装Maven并配置以及 IDEA配置Maven环境》,本文的上一篇为《 全面深入详解IOC/DI注解开发》 Spring为了使用注解简化开发,并没有提供

    2024年02月04日
    浏览(57)
  • Spring高手之路——深入理解与实现IOC依赖查找与依赖注入

    本文从 xml 开始讲解,注解后面给出   首先,我们需要明白什么是 IOC (控制反转)和依赖查找。在 Spring Framework 中,控制反转是一种设计模式,可以帮助我们解耦模块间的关系,这样我们就可以把注意力更多地集中在核心的业务逻辑上,而不是在对象的创建和管理上。  

    2024年02月06日
    浏览(58)
  • Spring高手之路1——深入理解与实现IOC依赖查找与依赖注入

    本文从 xml 开始讲解,注解后面给出   首先,我们需要明白什么是 IOC (控制反转)和依赖查找。在 Spring Framework 中,控制反转是一种设计模式,可以帮助我们解耦模块间的关系,这样我们就可以把注意力更多地集中在核心的业务逻辑上,而不是在对象的创建和管理上。  

    2024年02月09日
    浏览(60)
  • Spring-1-深入理解Spring XML中的依赖注入(DI):简化Java应用程序开发

    前两篇文章我们介绍了什么是Spring,以及Spring的一些核心概念,并且快速快发一个Spring项目,以及详细讲解IOC,今天详细介绍一些DI(依赖注入) 能够配置setter方式注入属性值 能够配置构造方式注入属性值 能够理解什么是自动装配 思考:向一个类中传递数据的方式有几种?(给类

    2024年02月13日
    浏览(50)
  • Spring框架IOC容器和DI依赖注入

    IOC(Invertion Of Control):控制反转,使用对象时,由使用new创建对象转变为由外部提供对象,此过程中对象的创建控制权由程序转移到外部的思想称之为控制反转. DI(Dependency Injection):依赖注入,在容器中建立bean与bean之间的关系的过程,称之为依赖注入 pom.xml依赖引入 BookDao BookDaoImpl Book

    2023年04月09日
    浏览(89)
  • CommunityToolkit.Mvvm8.1 IOC依赖注入控制反转(5)

      本系列文章导航 https://www.cnblogs.com/aierong/p/17300066.html https://github.com/aierong/WpfDemo (自我Demo地址) 希望提到的知识对您有所提示,同时欢迎交流和指正 作者:aierong 出处:https://www.cnblogs.com/aierong     CommunityToolkit.Mvvm包不提供ioc功能,但是官方建议使用:Microsoft.Extensions.DependencyInject

    2023年04月14日
    浏览(52)
  • 使用 Spring 实现控制反转和依赖注入

    在本文中,我们将介绍 IoC (控制反转)和 DI (依赖注入)的概念,以及如何在 Spring 框架中实现它们。 控制反转是软件工程中的一个原则,它将对象或程序的某些部分的控制权转移给容器或框架。我们最常在面向对象编程的上下文中使用它。 与传统编程相比,传统编程中我

    2024年02月13日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包