Spring 实战(第五版)
  • Spring 实战(第 5 版)
  • 第一部分 Spring 基础
  • 第 1 章 Spring 入门
    • 1.1 什么是 Spring?
    • 1.2 初始化 Spring 应用程序
      • 1.2.1 使用 Spring Tool Suite 初始化 Spring 项目
      • 1.2.2 检查 Spring 项目结构
    • 1.3 编写 Spring 应用程序
      • 1.3.1 处理 web 请求
      • 1.3.2 定义视图
      • 1.3.3 测试控制器
      • 1.3.4 构建并运行应用程序
      • 1.3.5 了解 Spring Boot DevTools
      • 1.3.6 回顾
    • 1.4 俯瞰 Spring 风景线
      • 1.4.1 Spring 核心框架
      • 1.4.2 Spring Boot
      • 1.4.3 Spring Data
      • 1.4.4 Spring Security
      • 1.4.5 Spring Integration 和 Spring Batch
      • 1.4.6 Spring Cloud
    • 1.5 小结
  • 第 2 章 开发 Web 应用程序
    • 2.1 展示信息
      • 2.1.1 建立域
      • 2.1.2 创建控制器类
      • 2.1.3 设计视图
    • 2.2 处理表单提交
    • 2.3 验证表单输入
      • 2.3.1 声明验证规则
      • 2.3.2 在表单绑定时执行验证
      • 2.3.3 显示验证错误
    • 2.4 使用视图控制器
    • 2.5 选择视图模板库
      • 2.5.1 缓存模板
    • 2.6 小结
  • 第 3 章 处理数据
    • 3.1 使用 JDBC 读写数据
      • 3.1.1 为域适配持久化
      • 3.1.2 使用 JdbcTemplate
      • 3.1.3 定义模式并预加载数据
      • 3.1.4 插入数据
    • 3.2 使用 Spring Data JPA 持久化数据
      • 3.2.1 添加 Spring Data JPA 到数据库中
      • 3.2.2 注解域作为实体
      • 3.2.3 声明 JPA repository
      • 3.2.4 自定义 JPA repository
    • 3.3 小结
  • 第 4 章 Spring 安全
    • 4.1 启用 Spring Security
    • 4.2 配置 Spring Security
      • 4.2.1 内存用户存储
      • 4.2.2 基于 JDBC 的用户存储
      • 4.2.3 LDAP 支持的用户存储
      • 4.2.4 自定义用户身份验证
    • 4.3 保护 web 请求
      • 4.3.1 保护请求
      • 4.3.2 创建用户登录页面
      • 4.3.3 登出
      • 4.3.4 阻止跨站请求伪造攻击
    • 4.4 了解你的用户
    • 4.5 小结
  • 第 5 章 使用配置属性
    • 5.1 微调自动配置
      • 5.1.1 理解 Spring 环境抽象
      • 5.1.2 配置数据源
      • 5.1.3 配置嵌入式服务器
      • 5.1.4 配置日志
      • 5.1.5 使用特殊的属性值
    • 5.2 创建自己的配置属性
      • 5.2.1 定义配置属性持有者
      • 5.2.2 声明配置属性元数据
    • 5.3 使用 profile 文件进行配置
      • 5.3.1 定义特定 profile 的属性
      • 5.3.2 激活 profile 文件
      • 5.3.3 有条件地使用 profile 文件创建 bean
    • 5.4 小结
  • 第二部分 集成 Spring
  • 第 6 章 创建 REST 服务
    • 6.1 编写 RESTful 控制器
      • 6.1.1 从服务器获取数据
      • 6.1.2 向服务器发送数据
      • 6.1.3 更新服务器上的资源
      • 6.1.4 从服务器删除数据
    • 6.2 启用超媒体
      • 6.2.1 添加超链接
      • 6.2.2 创建资源装配器
      • 6.2.3 嵌套命名关系
    • 6.3 启用以数据为中心的服务
      • 6.3.1 调整资源路径和关系名称
      • 6.3.2 分页和排序
      • 6.3.3 添加用户端点
      • 6.3.4 向 Spring Data 端点添加用户超链接
    • 6.4 小结
  • 第 7 章 调用 REST 服务
    • 7.1 使用 RestTemplate 调用 REST 端点
      • 7.1.1 请求 GET 资源
      • 7.1.2 请求 PUT 资源
      • 7.1.3 请求 DELETE 资源
      • 7.1.4 请求 POST 资源
    • 7.2 使用 Traverson 引导 REST API
    • 7.3 小结
  • 第 8 章 发送异步消息
    • 8.1 使用 JMS 发送消息
      • 8.1.3 接收 JMS 消息
      • 8.1.2 使用 JmsTemplate 发送消息
      • 8.1.1 设置 JMS
    • 8.2 使用 RabbitMQ 和 AMQP
      • 8.2.1 添加 RabbitMQ 到 Spring 中
      • 8.2.2 使用 RabbitTemplate 发送消息
      • 8.2.3 从 RabbitMQ 接收消息
    • 8.3 使用 Kafka 发送消息
      • 8.3.1 在 Spring 中设置 Kafka
      • 8.3.2 使用 KafkaTemplate 发送消息
      • 8.3.3 编写 Kafka 监听器
    • 8.4 小结
  • 第 9 章 集成 Spring
    • 9.1 声明简单的集成流
      • 9.1.1 使用 XML 定义集成流
      • 9.1.2 在 Java 中配置集成流
      • 9.1.3 使用 Spring Integration 的 DSL 配置
    • 9.2 探索 Spring Integration
      • 9.2.1 消息通道
      • 9.2.2 过滤器
      • 9.2.3 转换器
      • 9.2.4 路由
      • 9.2.5 分割器
      • 9.2.6 服务激活器
      • 9.2.7 网关
      • 9.2.8 通道适配器
      • 9.2.9 端点模块
    • 9.3 创建 Email 集成流
    • 9.4 总结
  • 第三部分 响应式 Spring
  • 第 10 章 Reactor 介绍
    • 10.1 理解响应式编程
      • 10.1.1 定义响应式流
    • 10.2 Reactor
      • 10.2.1 图解响应式流
      • 10.2.2 添加 Reactor 依赖
    • 10.3 通用响应式操作实战
      • 10.3.1 创建响应式类型
      • 10.3.2 响应式类型结合
      • 10.3.3 转换和过滤响应式流
      • 10.3.4 对反应类型执行逻辑操作
    • 10.4 总结
  • 第 11 章 开发响应式 API
    • 11.1 使用 Spring WebFlux
      • 11.1.1 Spring WebFlux 介绍
      • 11.1.2 编写响应式 Controller
    • 11.2 定义函数式请求处理程序
    • 11.3 测试响应式 Controller
      • 11.3.1 测试 GET 请求
      • 11.3.2 测试 POST 请求
      • 11.3.3 使用线上服务器进行测试
    • 11.4 响应式消费 REST API
      • 11.4.1 通过 GET 方式获取资源
      • 11.4.2 通过 POST 方式发送资源
      • 11.4.3 删除资源
      • 11.4.4 处理请求错误
      • 11.4.5 请求转换
    • 11.5 保护响应式 web API
      • 11.5.1 配置响应式 Web 安全
      • 11.5.2 配置响应式用户信息服务
    • 11.6 总结
  • 第 12 章 响应式持久化数据
    • 12.1 理解 Spring Data 响应式历程
      • 12.1.1 Spring Data 响应式精髓
      • 12.1.2 在响应式与非响应式之间进行转换
      • 12.1.3 开发响应式库
    • 12.2 使用响应式 Cassandra 库
      • 12.2.1 开启 Spring Data Cassandra
      • 12.2.2 理解 Cassandra 数据模型
      • 12.2.3 Cassandra 持久化实体映射
      • 12.2.4 编写响应式 Cassandra 库
    • 12.3 编写响应式 MongoDB 库
      • 12.3.1 开启Spring Data MongonDB
      • 12.3.2 MongoDB 持久化实体映射
      • 12.3.3 编写响应式 MongoDB 库
    • 12.4 总结
  • 第四部分 云原生 Spring
  • 第 13 章 服务发现
    • 13.1深入思考微服务
    • 13.2 配置服务注册
      • 13.2.1 配置 Eureka
      • 13.2.2 扩展 Eureka
    • 13.3 注册并发现服务
      • 13.3.1 配置 Eureka 客户端属性
      • 13.3.2 消费服务
    • 13.4 总结
  • 第 14 章 配置管理
    • 14.1 共享配置
    • 14.2 运行配置服务器
      • 14.2.1 启动配置服务器
      • 14.2.2 填写配置库
    • 14.3 消费共享的配置
    • 14.4 服务应用程序和特定配置文件的属性
      • 14.4.1 服务特定应用程序的属性
      • 14.4.2 服务配置文件属性
    • 14.5 为配置的属性加密
      • 14.5.1 在 Git 中加密属性
      • 14.5.2 在 Vault 中存储密码
    • 14.6 远程刷新配置属性
      • 14.6.1 手动刷新配置属性
      • 14.6.2 自动刷新配置属性
    • 14.7 总结
  • 第 15 章 处理失败和时延
    • 15.1 了解断路器
    • 15.2 定义断路器
      • 15.2.1 缓解时延
      • 15.2.2 管理断路器阈值
    • 15.3 管理失败事件
      • 15.3.1 介绍 Hystrix 面板
      • 15.3.2 了解 Hystrix 线程池
    • 15.4 聚合多个 Hystrix 流
    • 15.5 总结
  • 第五部分 部署Spring
  • 第 16 章 使用 SpringBoot Actuator
    • 16.1 介绍 Actuator
      • 16.1.1 配置 Actuator 基本路径
      • 16.1.2 启用和禁用 Actuator 端点
    • 16.2 使用 Actuator 端点
      • 16.2.1 获取重要的应用程序信息
      • 16.2.2 查看配置详细信息
      • 16.2.3 查看应用程序活动
      • 16.2.4 利用运行时指标
    • 16.3 自定义 Actuator
      • 16.3.1 向 /info 端点提供信息
      • 16.3.2 自定义健康指标
      • 16.3.3 注册自定义指标
      • 16.3.4 创建自定义端点
    • 16.4 保护 Actuator
    • 16.5 总结
  • 第 17 章 管理 Spring
    • 17.1 使用 SpringBoot Admin
      • 17.1.1 创建 Admin 服务端
      • 17.1.2 注册 Admin 客户端
    • 17.2 深入 Admin 服务端
      • 17.2.1 查看普通应用程序运行状况和信息
      • 17.2.2 观察关键指标
      • 17.2.3 检查环境属性
      • 17.2.4 查看并设置 log 级别
      • 17.2.5 监控线程
      • 17.2.6 追踪 HTTP 请求
    • 17.3 保护 Admin 服务端
      • 17.3.1 在 Admin 服务端中启用登录
      • 17.3.2 使用 Actuator 进行认证
    • 17.4 总结
  • 第 18 章 使用 JMX 监控 Spring
    • 18.1 使用 Actuator MBean
    • 18.2 创建自己的 MBean
    • 18.3 发送通知
    • 18.4 总结
  • 第 19 章 部署 Spring
    • 19.1 权衡部署选项
    • 19.2 构建并部署 WAR 文件
    • 19.3 将 JAR 文件推送到 Cloud Foundry
    • 19.4 在 Docker 容器中运行 SpringBoot
    • 19.5 终章
    • 19.6 总结
由 GitBook 提供支持
在本页

这有帮助吗?

  1. 第 1 章 Spring 入门
  2. 1.2 初始化 Spring 应用程序

1.2.2 检查 Spring 项目结构

上一页1.2.1 使用 Spring Tool Suite 初始化 Spring 项目下一页1.3 编写 Spring 应用程序

最后更新于5年前

这有帮助吗?

在 IDE 中加载项目后,将其展开以查看其中包含的内容。图 1.6 显示了 Spring Tool Suite 中扩展的 Taco Cloud 项目。

你可能会认为这是典型的 Maven 或 Gradle 项目结构,其中应用程序源代码位于src/main/java 下,测试代码位于 src/test/java 下,非 Java 资源位于 src/main/resources 下 。在该项目结构中,需要注意以下事项:

  • mvnw 和 mvnw.cmd —— 这些是 Maven 包装器脚本。即使你的计算机上没有安装 Maven,也可以使用这些脚本构建项目。

  • pom.xml —— 这是 Maven 构建规范,一会儿我们将对此进行更深入的研究。

  • TacoCloudApplication.java —— 这是引导项目的 Spring Boot 主类。稍后,我们将在这节详细介绍。

  • application.properties —— 该文件最初为空,但提供了一个可以指定配置属性的地方。我们将在本章中对此文件进行一些修改,但在第 5 章中将详细介绍配置属性。

  • static —— 在此文件夹中,可以放置要提供给浏览器的任何静态内容(图像、样式表、JavaScript 等),最初为空。

  • templates —— 在此文件夹中,放置用于向浏览器呈现内容的模板文件。最初为空,但很快会添加 Thymeleaf 模板。

  • TacoCloudApplicationTests.java —— 这是一个简单的测试类,可确保成功加载 Spring 应用程序上下文。开发应用程序时,将添加更多的测试。

随着 Taco Cloud 应用程序的增长,将使用 Java 代码、图像、样式表、测试以及其他可帮助完成项目的附带材料来填充此准系统的项目结构。但是与此同时,让我们更深入地研究 Spring Initializr 提供的一些选项。

探索构建规范

填写 Initializr 表单时,指定应使用 Maven 构建项目。因此,Spring Initializr 给了你一个 pom.xml 文件,该文件已经填充了你所做的选择。程序清单 1.1 显示了 Initializr 提供的整个 pom.xml 文件。

程序清单 1.1 初始化 Maven 构建规范
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
        http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>sia</groupId>
    <artifactId>taco-cloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    
    <name>taco-cloud</name>
    <description>Taco Cloud Example</description>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <scope>test</scope>
        </dependency>
        
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>htmlunit-driver</artifactId>
            <scope>test</scope>
        </dependency>
    
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

xml 文件中第一个值得注意的项是 <packaging> 元素。你选择将应用程序构建为可执行的 JAR 文件,而不是 WAR 文件。这可能是你所做的最奇怪的选择之一,特别是对于 web 应用程序。毕竟,传统的 Java web 应用程序被打包为 WAR 文件,而 JAR 文件是库和偶尔使用的桌面 UI 应用程序的首选打包方式。

选择 JAR 打包是一种不切实际的选择。虽然 WAR 文件非常适合部署到传统的 Java 应用服务器,但是它们并不适合大多数云平台。尽管一些云平台(如 Cloud Foundry)能够部署和运行 WAR 文件,但是所有的 Java 云平台都能够运行可执行的 JAR 文件。因此,Spring Initializr 默认为 JAR 打包,除非你不让它这样做。

如果打算将应用程序部署到传统的 Java 应用服务器,那么需要选择 WAR 打包并包含 web 初始化类。我们将在第 2 章中更详细地讨论如何构建 WAR 文件。

接下来,请注意 <parent> 元素,更具体地说,注意它的 <version> 子元素。这指定您的项目将 spring-boot-starter-parent 作为它的父 POM。除此之外,这个父 POM 还为 Spring 项目中常用的几个库提供依赖项管理。对于父 POM 覆盖的那些库,不必指定版本,因为它是从父 POM 继承的。2.0.4.RELEASE 版本,表示你正在使用 Spring Boot 2.0.4,这样项目将使用继承自 Spring Boot 版本中定义的依赖项管理。

在讨论依赖项时,请注意在 <dependencies> 元素下声明了三个依赖项。前两个看起来应该比较熟悉。它们直接对应于在单击 Spring Tool Suite 新建项目向导中的 Finish 按钮之前选择的 Web 和 Thymeleaf 依赖项。第三个依赖项提供了许多有用的测试功能,你不必选中包含它的方框,因为 Spring Initializr 假定(希望是正确的)你将编写测试。

你可能还会注意到,所有这三个依赖项的 artifact ID 中都有 starter 这个词。Spring Boot starter 依赖项的特殊之处在于,它们本身通常没有任何库代码,而是间接地引入其他库。这些 starter 依赖提供了三个主要的好处:

  • 构建的文件将会小得多,也更容易管理,因为不需要对每一个可能需要的库都声明一个依赖项。

  • 可以根据它们提供的功能来考虑需要的依赖关系,而不是根据库名来考虑。如果正在开发一个 web 应用程序,那么将添加 web starter 依赖项,而不是一个编写 web 应用程序的各个库的清单。

  • 不用担心 library 版本问题。可以相信的是,对于给定版本的 Spring Boot,可间接地引入的库的版本将是兼容的,只需要考虑使用的是哪个版本的 Spring Boot。

最后,构建规范以 Spring Boot 插件结束。这个插件执行一些重要的功能:

  • 提供了一个 Maven 编译目标,让你能够使用 Maven 运行应用程序。这将在第 1.3.4 节中尝试实现这个目标。

  • 确保所有的依赖库都包含在可执行的 JAR 文件中,并且在运行时类路径中可用。

  • 在 JAR 文件中生成一个 manifest 文件,表示引导类(在本书例子中是 TacoCloudApplication)是可执行 JAR 的主类。

说到引导类,让我们打开它,仔细看看。

引导应用程序

因为将从一个可执行的 JAR 运行应用程序,所以在运行 JAR 文件时,有一个主类来执行是很重要的。还需要至少一个最小的 Spring 配置文件来引导应用程序。这就是将在 TacoCloudApplication 类中找到的内容,如下程序清单 1.2 所示。

程序清单 1.2 Taco Cloud 引导类
package tacos;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class TacoCloudApplication {
    public static void main(String[] args) {
        SpringApplication.run(TacoCloudApplication.class, args);
    }
}

虽然 TacoCloudApplication 中只有很少的代码,但是其中包含了相当丰富的内容。最强大的代码行之一也是最短的代码行之一。@SpringBootApplication 注释清楚地表明这是一个 Spring 引导应用程序。但是 @SpringBootApplication 中有更多的东西。@SpringBootApplication 是一个组合了其他三个注释的复合应用程序:

  • @SpringBootConfiguration —— 指定这个类为配置类。尽管这个类中还没有太多配置,但是如果需要,可以将 Javabased Spring Framework 配置添加到这个类中。实际上,这个注释是@Configuration 注释的一种特殊形式。

  • @EnableAutoConfiguration —— 启用 Spring 自动配置。稍后我们将详细讨论自动配置。现在,要知道这个注释告诉 Spring Boot 自动配置它认为需要的任何组件。

  • @ComponentScan —— 启用组件扫描。这允许你声明其他带有 @Component、@Controller、@Service 等注释的类,以便让 Spring 自动发现它们并将它们注册为 Spring 应用程序上下文中的组件。

TacoCloudApplication 的另一个重要部分是 main() 方法。这个方法将在执行 JAR 文件时运行。在大多数情况下,这种方法是样板代码;编写的每个 Spring 引导应用程序都有一个类似或相同的方法(尽管类名不同)。

main() 方法调用 SpringApplication 类上的静态 run() 方法,该方法执行应用程序的实际引导,创建Spring 应用程序上下文。传递给 run() 方法的两个参数是一个配置类和命令行参数。虽然传递给 run() 的配置类不必与引导类相同,但这是最方便、最典型的选择。

你可能不需要更改引导类中的任何内容。对于简单的应用程序,你可能会发现在引导类中配置一两个其他组件很方便,但是对于大多数应用程序,最好为任何没有自动配置的东西创建一个单独的配置类。你将在本书的整个过程中定义几个配置类,因此请注意这些细节。

测试应用程序

测试是软件开发的一个重要部分。认识到这一点后,Spring Initializr 提供了一个测试类。程序清单 1.3 显示了基准测试类。

程序清单 1.3 基准应用测试
package tacos;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
​
@RunWith(SpringRunner.class)
@SpringBootTest
public class TacoCloudApplicationTests {
    @Test
    public void contextLoads() {
    }
}

在 TacoCloudApplicationTests 中没有太多东西:类中的一个测试方法是空的。尽管如此,这个测试类确实执行了必要的检查,以确保 Spring 应用程序上下文能够成功加载。如果做了任何阻止创建 Spring 应用程序上下文的更改,则此测试将失败,这样你就可以通过解决问题来应对。

还要注意用 @RunWith(SpringRunner.class) 注释的类。@RunWith 是一个 JUnit 注释,提供了一个测试运行器来引导 JUnit 运行测试用例。请将清单 1.3 看作是对它的基准应用程序测试,即将插件应用到 JUnit 以提供自定义测试行为。在本例中,JUnit 被赋予了 SpringRunner,这是一个由 Spring 提供的测试运行程序,它提供了创建一个 Spring 应用程序上下文的功能,以供测试运行。

其他名字的测试运行器

如果你已经熟悉编写 Spring 测试,或者正在查看一些现有的基于 Spring 的测试类,那么你可能已经看到了一个名为 SpringJUnit4ClassRunner 的测试运行器。SpringRunner 是 SpringJUnit4ClassRunner 的别名,它是在 Spring 4.3 中引入的,用于删除与特定版本的 JUnit (例如,JUnit4)的关联。毫无疑问,别名更易于阅读和输入。

@SpringBootTest 告诉 JUnit 使用 Spring 引导功能引导测试。现在,把它看作是在 main() 方法中调用 SpringApplication.run() 的测试类就足够了。在本书的过程中,将多次看到 @SpringBootTest,我们将揭示它的一些功能。

最后,还有测试方法本身。尽管 @RunWith(SpringRunner.class) 和 @SpringBootTest 的任务是加载用于测试的 Spring 应用程序上下文,但是如果没有任何测试方法,它们将没有任何事情要做。即使没有任何断言或任何类型的代码,这个空的测试方法也会调用两个注释完成它们的工作,并加载 Spring 应用程序上下文。如果运行过程中有任何问题,测试就会失败。

至此,我们已经完成了对 Spring Initializr 提供的代码的回顾。看到了一些用于开发 Spring 应用程序的样板基础,但是仍然没有编写任何代码。现在,启动 IDE,掸掉键盘上的灰尘,并向 Taco Cloud 应用程序添加一些定制代码。

图 1.6 Spring Tool Suite 中的 Spring 项目结构