- 内容提要
- 作者简介
- 译者简介
- 前言
- HTTP
- Servlet 和 JSP
- 下载 Spring 或使用 STS 与 Maven/Gradle
- 手动下载 Spring
- 使用 STS 和 Maven/Gradle
- 下载 Spring 源码
- 本书内容简介
- 下载示例应用
- 第 1 章Spring 框架
- 第 2 章模型 2 和 MVC 模式
- 第 3 章Spring MVC 介绍
- 第 4 章基于注解的控制器
- 第 5 章数据绑定和表单标签库
- 第 6 章转换器和格式化
- 第 7 章验证器
- 第 8 章表达式语言
- 第 9 章JSTL
- 第 10 章国际化
- 第 11 章上传文件
- 第 12 章下载文件
- 第 13 章应用测试
- 附录 A Tomcat
- 附录 B Spring Tool Suite 和 Maven
- 附录 C Servlet
- 附录 D JavaServer Pages
- 附录 E 部署描述符
第 1 章Spring 框架
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,而无需直接处理。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论