Spring和其IOC和DI

spring是干什么的?

Spring 是一个开源的Java应用程序框架,最初由Rod Johnson在2003年创建。Spring 的初衷是为了简化企业级Java应用程序的开发,并提供一种灵活、可扩展、易于测试和维护的编程模型。

 

先来看看Spring 框架诞生的初衷:

  1. 简化开发:Spring 提供了一个轻量级的容器,它可以管理和组装应用程序中的对象(称为IoC容器),使开发人员能够更加专注于业务逻辑层的开发,而不需要过多关注底层的复杂性。

  2. 提升可测试性:Spring 框架设计时考虑了可测试性,它支持依赖注入(DI)和面向接口编程,使得应用程序的各个组件能够方便地进行单元测试和集成测试。

  3. 促进松耦合:Spring 采用了松耦合的设计思想,通过依赖注入和面向接口编程,将组件之间的依赖关系从代码中解耦出来,降低了组件之间的耦合度,使得代码更加灵活、可复用和可维护。

  4. 支持面向切面编程(AOP):Spring 提供了对面向切面编程的支持,可以在不改变原有业务逻辑的情况下,通过切面将横切关注点(如事务管理、日志记录等)与核心业务逻辑进行解耦,提高了代码的模块化和复用性。

  5. 丰富的功能扩展:Spring 框架提供了众多的可插拔的功能模块,如数据访问、事务管理、安全认证、Web开发等,开发人员可以根据需求灵活地选择和集成相应的模块,以满足不同应用的需求。

总的来说,Spring 的初衷是为了提供一种简化开发、增强可测试性、促进松耦合和支持面向切面编程的编程模型,以帮助开发人员构建可靠、可扩展和易于维护的企业级Java应用程序。

spring框架的模型:

当我们谈论Spring框架时,可以将其比喻为一个大型的工具箱。这个工具箱里包含了不同的模块,每个模块都有自己特定的功能,但它们又可以相互协作。

比如说:

        Core模块就是这个工具箱的核心部分,它负责控制整个Spring框架的执行流程和管理各个组件。类似于工人在使用工具箱时,会先从里面拿出一个最基本的工具。

        AOP模块就像是给这个工具箱加上了一个增强器,它允许我们将一些通用的操作(比如日志记录、性能监控)独立出来,以切面的方式应用到我们的应用程序中。就好比我们在使用工具箱时,有一个能够自动进行某些处理的工具。

        DAO模块则是对JDBC进行封装的工具,它使得我们能够更方便地访问数据库,并提供了事务管理的能力。就像在工具箱中放了一个专门处理连接和查询数据库的工具。

        ORM模块则提供了对常见的ORM框架(比如Hibernate)的支持,使得我们能够更轻松地操作数据库对象。可以把它想象成一个适配器,将数据库和应用程序之间的数据转换工作交给它来完成。

        Context模块就像是整个工具箱的管家,负责管理各个组件和资源。它提供了一种框架式的访问方式,使得我们可以方便地获取和管理Spring中的Bean对象。此外,它还提供了其他功能,如国际化、事件传播和验证。

        Web模块是建立在Context模块之上的,它专注于为Web应用程序提供支持。它可以与其他Web框架(比如Struts、JSF)进行集成,提供了一个适合Web开发的环境。

        Web MVC模块则是这个工具箱中的一个特殊工具,它专门用于构建Web应用程序中的MVC架构。它提供了各种功能和视图技术,帮助我们构建出功能完善的Web应用程序。

        可以说Spring框架就像一个功能强大的工具箱,里面包含了各种各样的工具模块,用来简化我们的开发过程,并提供了丰富的功能和支持。这些模块相互协作,让我们能够更高效、更方便地开发应用程序。

Spring的IOC和DI到底是为了什么?

在Spring框架中,IOC(Inversion of Control,控制反转)和DI(Dependency Injection,依赖注入)是紧密相关的概念。它们都是为了解决组件之间的依赖关系管理问题,提高代码的灵活性、可复用性和可测试性。

  1. 控制反转(IOC):IOC 是一种设计思想,它将对象的创建和管理工作交给了框架来完成,而不是由开发人员手动管理。传统上,对象的创建通常通过直接实例化或使用工厂模式来完成,而在IOC中,开发人员只需要定义对象所需的依赖关系,并将控制权交给框架。框架会负责创建对象、管理对象的生命周期,并将对象提供给需要它们的地方。

  2. 依赖注入(DI):DI 是实现IOC的具体方式之一。它是指通过构造函数、setter方法或接口注入等方式,将一个对象所需要的依赖关系注入到对象中。开发人员只需要声明对象所需的依赖,而不需要关心如何创建和提供这些依赖,框架会自动进行依赖的注入。这样,对象之间的耦合度就被降低了,同时也使得代码更加灵活、可扩展和易于测试。

因此,IOC和DI可以被视为一种编程模型,旨在解耦对象之间的依赖关系,并将对象的创建和管理工作交给框架来处理。通过将控制权反转给框架,并使用依赖注入的方式,开发人员可以更加专注于业务逻辑的实现,而不需要过多关注对象的创建和管理细节。这样可以提高代码的可维护性、可测试性,以及整体应用程序的灵活性和扩展性。

控制反转(IOC)和依赖注入(DI)的优点

好处:

使用控制反转(IOC)和依赖注入(DI)的好处如下:

  1. 解耦对象之间的依赖关系:传统的对象创建方式中,对象通常需要直接实例化或使用工厂模式来创建。这样会导致对象之间紧密耦合,难以复用和测试。而采用IOC和DI的方式,可以将对象之间的依赖关系解耦,降低它们之间的耦合度。

  2. 提高代码的灵活性和可维护性:通过IOC和DI,开发人员只需要声明对象所需的依赖关系,而不需要亲自负责对象的创建和管理。这样可以使代码更加灵活,易于修改和扩展。同时,将对象的创建和管理交给框架来处理,可以提高代码的可维护性,减少重复代码的编写。

  3. 支持单元测试和集成测试:使用IOC和DI可以方便地进行单元测试和集成测试。由于对象的依赖关系被解耦,可以轻松地用模拟对象替代真实的依赖对象进行测试,从而更容易编写和执行单元测试和集成测试。

  4. 促进代码的可扩展性:通过IOC和DI,可以方便地替换和切换依赖对象。当需求变化时,只需要修改配置文件或注解,而不需要改动源代码。这样可以提高代码的可扩展性,减少对现有代码的影响。

总结来说,使用控制反转和依赖注入可以解耦对象之间的依赖关系,提高代码的灵活性、可维护性和可测试性。它们使得开发人员更加专注于业务逻辑的实现,而不需要过多关注对象的创建和管理细节。这样可以提高开发效率,降低代码的复杂性,并促进代码的可扩展性和可重用性。

 IOC和DI=》举个例子:

举个例子来说明控制反转(IOC)和依赖注入(DI)的作用。

假设我们正在开发一个简单的图书管理系统,其中有以下几个类:`Book`(表示图书)、`Library`(表示图书馆)和 `LibraryService`(提供图书管理的服务)。

在没有使用IOC和DI的情况下,我们可能会在 `LibraryService` 类中直接实例化 `Book` 和 `Library` 对象:


public class LibraryService {
    private Book book;
    private Library library;
    
    public LibraryService() {
        this.book = new Book();
        this.library = new Library();
    }
    
    // 省略其他方法
}

这样做的问题是,在 `LibraryService` 类中直接创建 `Book` 和 `Library` 对象,导致 `LibraryService` 类与 `Book` 和 `Library` 类紧密耦合在一起。如果后续需要修改 `Book` 或 `Library` 的实现方式,就需要修改 `LibraryService` 类的代码,违背了开闭原则。

现在,我们使用IOC和DI来改造上述代码,通过将对象的创建和管理交给框架来处理。

首先,创建 `Book` 和 `Library` 类,它们的实例将从外部注入到 `LibraryService` 类中:


public class Book {
    // 省略属性和方法
}

public class Library {
    // 省略属性和方法
}

public class LibraryService {
    private Book book;
    private Library library;
    
    public LibraryService(Book book, Library library) {
        this.book = book;
        this.library = library;
    }
    
    // 省略其他方法

接下来,在应用程序的配置文件或使用框架提供的注解方式,配置对象的依赖关系:


<!-- 配置对象的依赖关系 -->
<bean id="book" class="com.example.Book" />
<bean id="library" class="com.example.Library" />
<bean id="libraryService" class="com.example.LibraryService">
    <constructor-arg ref="book" />
    <constructor-arg ref="library" />
</bean>

或者使用注解方式:


@Component
public class Book {
    // 省略属性和方法
}

@Component
public class Library {
    // 省略属性和方法
}

@Component
public class LibraryService {
    private Book book;
    private Library library;
    
    @Autowired
    public LibraryService(Book book, Library library) {
        this.book = book;
        this.library = library;
    }
    
    // 省略其他方法

这样,框架会负责根据配置文件或注解,在创建 `LibraryService` 对象时自动注入 `Book` 和 `Library` 对象,使得它们之间的依赖关系解耦,并且不需要修改 `LibraryService` 类的代码。

通过使用IOC和DI,我们将对象的创建和管理交给了框架,降低了对象之间的耦合度,使代码更加灵活、可维护和可测试。当需要修改 `Book` 或 `Library` 的实现方式时,只需要调整配置文件或注解,而不需要修改 `LibraryService` 类的代码,这符合开闭原则,并且提高了代码的可扩展性和可重用性。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ヾ草木萤火(≧▽≦*)o

希望大家多多支持,我会继续分享

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值