返回介绍

第 1 章Spring 框架

发布于 2025-04-22 20:09:57 字数 3137 浏览 0 评论 0 收藏

Spring 框架是一个开源的企业应用开发框架,作为一个轻量级的解决方案,它包含 20 多个不同的模块。本书主要关注 Core、Spring Bean、Spring MVC 和 Spring MVC Test 模块。

本章主要介绍 Core 和 Spring Bean 这两个模块,以及它们如何提供依赖注入解决方案。为方便初学者,本书会深入讨论依赖注入概念的细节。后续介绍开发 MVC 应用的章节将会使用到本章介绍的技能。

依赖注入

在过去数年间,依赖注入技术作为代码可测试性的一个解决方案已经被广泛应用。实际上,Spring、谷歌 Guice 等框架都采用了依赖注入技术。那么,什么是依赖注入技术?

很多人在使用中并不区分依赖注入和控制反转(IoC),尽管 Martin Fowler 在其文章中已分析了两者的不同:

http://martinfowler.com/articles/injection.html

简单来说,依赖注入的情况如下。

有两个组件 A 和 B,A 依赖于 B。假定 A 是一个类,且 A 有一个方法 importantMethod 用到了 B,如下:

public class A {
  public void importantMethod() {
    B b = ... // get an instance of B
    b.usefulMethod();
    ...
  }
  ...
}

要使用 B,类 A 必须先获得组件 B 的实例引用。若 B 是一个具体类,则可通过 new 关键字直接创建组件 B 实例。但是,如果 B 是接口,且有多个实现,则问题就变得复杂了。我们固然可以任意选择接口 B 的一个实现类,但这也意味着 A 的可重用性大大降低了,因为无法采用 B 的其他实现。

依赖注入是这样处理此类情景的:接管对象的创建工作,并将该对象的引用注入需要该对象的组件。以上述情况为例,依赖注入框架会分别创建对象 A 和对象 B,将对象 B 注入到对象 A 中。

为了能让框架进行依赖注入,程序员需要编写特定的 set 方法或者构建方法。例如,为了能将 B 注入到 A 中,类 A 会被修改成如下形式:

public class A {
  private B b;
  public void importantMethod() {
    // no need to worry about creating B anymore
    // B b = ... // get an instance of B
    b.usefulMethod();
    ...
  }
  public void setB(B b) {
    this.b = b;
  }
}

修改后的类 A 新增了一个 set 方法,该方法将会被框架调用,以注入 B 的一个实例。由于对象依赖由依赖注入,类 A 的 importantMethod 方法不再需要在调用 B 的 usefulMethod 方法前去创建 B 的一个实例。

当然,也可以采用构造器方式注入,如下所示:

public class A {
  private B b;

  public A(B b) {
    this.b = b;
  }

  public void importantMethod() {
    // no need to worry about creating B anymore
    // B b = ... // get an instance of B
    b.usefulMethod();
    ...
  }
}

本例中,Spring 会先创建 B 的实例,再创建实例 A,然后把 B 注入到实例 A 中。

注:

Spring 管理的对象称为 beans。

通过提供一个控制反转容器(或者依赖注入容器),Spring 为我们提供一种可以“聪明”地管理 Java 对象依赖关系的方法。其优雅之处在于,程序员无需了解 Spring 框架的存在,更不需要引入任何 Spring 类型。

从 1.0 版本开始,Spring 就同时支持 setter 和构造器方式的依赖注入。从 2.5 版本开始,通过 Autowired 注解,Spring 支持基于 field 方式的依赖注入,但缺点是程序必须引入 org.springframework.beans.factory.annotation.Autowired,这对 Spring 产生了依赖,这样,程序无法直接迁移到另一个依赖注入容器间。

使用 Spring,程序几乎将所有重要对象的创建工作移交给 Spring,并配置如何注入依赖。Spring 支持 XML 或注解两种配置方式。此外,还需要创建一个 ApplicationContext 对象,代表一个 Spring 控制反转容器,org.springframework.context.ApplicationContext 接口有多个实现,包括 ClassPathXmlApplicationContext 和 FileSystemXmlApplicationContext。这两个实现都需要至少一个包含 beans 信息的 XML 文件。ClassPathXmlApplicationContext 尝试在类加载路径中加载配置文件,而 FileSystemXmlApplicationContext 则从文件系统中加载。

下面是从类路径中加载 config1.xml 和 config2.xml 的 ApplicationContext 创建的一个代码示例。

ApplicationContext context = new ClassPathXmlApplicationContext(
    new String[] {"config1.xml", "config2.xml"});

可以通过调用 ApplicationContext 的 getBean 方法获得对象。

Product product = context.getBean("product", Product.class);

getBean 方法会查询 id 为 product 且类型为 Product 的 bean 对象。

注:

理想情况下,我们只需在测试代码中创建一个 ApplicationContext,应用程序本身无需处理。对于 Spring MVC 应用,可以通过一个 Spring Servlet 来处理 ApplicationContext,而无需直接处理。

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。