资源
简介
本笔记是对 Java Brains 出品的关于 Spring Boot 快速入门 视频教程的概要笔记。通过该视频将会 学到如何使用 Spring Boot 创建完整的端到端的 Spring 应用,以及提供一个使用 Spring 技术构建、具备数据库支持的 REST API 的实践指南。
介绍 Spring Boot
Spring Boot 是什么
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.
Spring Boot 可以轻松创建独立的、生产级的基于 Spring 的应用程序,且可以轻易“运行”它。
Spring 痛点
- 框架庞大
- 步骤繁杂的设置、配置、构建及部署
Spring Boot 有何好处
- 自决断性 (Opinionated)
默认一套配置,且支持定制修改 - 约定优于配置 (Convention over configuration)
默认约定适用大部分场景,减少配置 - 独立性 (Stand alone)
打包一切,使得Spring 的应用可独自运行
Spring Boot 示例
- JDK 8 安装及配置
-
查看所有安装版本
Reion@MBPr ~$ /usr/libexec/java_home -V
-
编辑 .bash_profile 文件,导出 JAVA_HOME
export JAVA_HOME=`/usr/libexec/java_home -v 1.8`
-
-
IDE
Spring STS、IntelliJ IDEA - Maven
- Maven 是什么
用来管理项目依赖关系的一个工具,自动从仓库下载依赖包
- Maven 是什么
- 创建 Spring Boot 项目
-
打开 STS,【Package Explorer】窗体右键,选择【New】后选取【Maven Project】
-
弹出【New Maven Project】窗口中勾选【Create a simple project(skip archetype selection)】,点击【Next】
-
Group Id 输入
io.javabrains.springbootquickstart
、Artifact Id 输入course-api
、Name 输入Java Brains Course API
,点击【Finish】 -
完成后的目录结构
course-api └── pom.xml └── src │ └── main │ │ └── java │ │ └── resources │ └── test │ └── java │ └── resources └── target └── classes │ └── META-INF │ └── MANIFEST.MF │ └── maven │ └── io.javabrains.springbootquickstart │ └── course-api │ └── pom.properties │ └── pom.xml └── test-classes
-
修改 pom.xml 文件,增加 Spring Boot 相关依赖
<!-- 告诉 Maven 依赖的 spring boot 版本信息 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.2.RELEASE</version> </parent> <!-- 具体 spring boot 依赖 --> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <!-- JDK 版本 --> <properties> <java.version>1.8</java.version> </properties>
-
增加 Spring Boot 启动类 CourseApiApp.java
package io.javabrains.springbootstarter; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; // 标注此为 Spring Boot 应用入口 @SpringBootApplication public class CourseApiApp { public static void main(String[] args) { // 启动 SpringApplication.run(CourseApiApp.class, args); } }
到此完成 Spring Boot 应用的环境搭建及配置,点击运行后竟然能够启动了,而且从后台日志可以看出包括 WebApplicationContext、Tomcat等都初始化启动完成了,果真是打包一切,开箱即运行!
2018-04-03 12:52:02.569 INFO 3385 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http) 2018-04-03 12:52:02.582 INFO 3385 --- [ main] i.j.springbootstarter.CourseApiApp : Started CourseApiApp in 4.117 seconds (JVM running for 4.615)
启动 Spring Boot,
SpringApplication.run(CourseApiApp.class, args)
这段静态方法将会执行如下步骤:- 设置默认配置
- 启动 Spring 容器应用上下文
- 进行类路径下的扫描(获取注解进行相关初始化)
- 启动 Tomcat 服务器
-
-
增加 REST 控制器 1
HelloController.java
package io.javabrains.springbootstarter.hello; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; // 标注此为一个控制器 @RestController public class HelloController { /* * 将 `/hello` URL 映射到 `sayHi` 方法 * * Tips: @RequestMapping 默认映射所有 http 请求方法 * 例如:GET、POST、PUT 等等 */ @RequestMapping("/hello") public String sayHi() { return "Hi"; } }
Topic.java
package io.javabrains.springbootstarter.topic; public class Topic { private String id; private String name; private String description; public Topic() {} public Topic(String id, String name, String description) { this.id = id; this.name = name; this.description = description; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
TopicController.java
package io.javabrains.springbootstarter.topic; import java.util.Arrays; import java.util.List; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class TopicController { // 返回一个列表对象的方法,对象以 Json 格式表示 @RequestMapping("/topics") public List<Topic> getAllTopics() { return Arrays.asList( new Topic("spring", "Spring Framework", "Spring Framework Description"), new Topic("java", "Core java", "Core java Description"), new Topic("javascript", "Javascript", "Javascript Description")); } }
启动应用,分别访问如下 URL:
http://localhost:8080/hello http://localhost:8080/topics
得到相应结果:
Hi
[ { "id": "spring", "name": "Spring Framework", "description": "Spring Framework Description" }, { "id": "java", "name": "Core java", "description": "Core java Description" }, { "id": "javascript", "name": "Javascript", "description": "Javascript Description" } ]
实现原理
从上面示例可知,只需简单的注解式的编写控制器就能实现一个客户端到服务端的请求调用,没有繁琐的配置、部署及启动操作。其实在幕后,这些繁琐操作都被 Spring Boot 隐藏起来,从而达到简化操作的目的。
那么 Spring Boot 如何做到这点呢?
-
材料清单
Spring Boot 通过 bom.xml 提供应用所需的所有预设配置及依赖组合清单,这份被验证过的清单使得应用配置、部署及运行的所有操作对开发人员完全透明化。 -
嵌入 Servlet 容器
采用内嵌方式后,使得 Spring Boot 能够接管及配置 Servlet 容器。以前对容器的配置操作现在被整合提取到应用的相应配置中,使得以前分散的模块聚集成一个独立的应用,这对实现 微服务架构 2 是一个良好基础。
参考 Spring Boot 文档关于嵌入式 Servlet 容器支持 小节,为了实现从 Servlet 容器管理 ServletContainerInitializer 进而引导 Spring Web 应用初始化 转化为 由 Spring 管理 ServletContextInitializer 引导并配置嵌入式 Servlet 容器 的目的,应该注册实现org.springframework.boot.web.servlet.ServletContextInitializer
接口的 bean,其onStartup
方法提供对ServletContext
的访问。
Spring MVC - 视图层
Spring MVC 原理
Spring Web MVC is the original web framework built on the Servlet API and included in the Spring Framework from the very beginning. The formal name “Spring Web MVC” comes from the name of its source module spring-webmvc but it is more commonly known as “Spring MVC”.
Spring Web MVC 是构建在 Servlet API 上的最初的 Web 框架,从一开始就包含在 Spring 框架中。正式名称“Spring Web MVC”来自其源模块 spring-webmvc 的名称, 但它通常被称为 “Spring MVC”。
正如 Spring 官方文档 所述,Spring MVC 是构建在 Java Serverlet API 之上,其核心包含一个 DispatcherServlet ,此 Servlet 包含一个根 WebApplicationContext 上下文,此根上下文持有与之相关的 ServletContext 引用,及此 ServletContext 上下文相关的 Servlet 信息。
根上下文下又包括子上下文,根 WebApplicationContext 通常包含需要跨多个 Servlet 实例共享的基础架构 bean,例如:数据存储库和业务服务。这些 bean 被有效地继承,并且可以在特定的 Servlet 的子 WebApplicationContext 中重写(即重新声明),子上下文通常包含给定 Servlet 的本地 bean,例如:控制器、映射处理、视图解析器。
图一 上下文层级关系
由于 Spring Boot 使用 Spring 配置来引导自身及嵌入的 Servlet 容器,所以在 Servlet 容器遵循不同的初始化顺序。Filter、Servlet 是交由 Spring 配置声明,并注册到内嵌的 Servlet 容器中。
REST API
REST 架构把通过 HTTP 协议预定义的请求方法来操作服务端的各种资源,下面以 Topic 为例,设计如下 REST API:
请求方法 | URL | 方法说明 |
---|---|---|
GET | /topics | 得到所有主题 |
GET | /topics/id | 得到某个 id 的主题 |
POST | /topics | 新增一个主题 |
PUT | /topics/id | 更新某个 id 的主题 |
DELETE | /topics/id | 删除某个 id 的主题 |
-
代码结构:
└── io └── javabrains └── springbootstarter └── CourseApiApp.java └── topic └── Topic.java └── TopicController.java └── TopicService.java
实现源代码:course-api
Http 请求模拟工具:Postman
生成 Spring Boot 项目
生成方式
- 使用 Spring Initializr
- 打开链接 https://start.spring.io/
- 按页面导引填入相关信息,选择依赖模块
- 点击【Generate Project】生成一个压缩包
- 下载并解压
- 用 IDE 导入 Maven 工程方式即可开始开发
-
使用 Spring Boot CLI
详细参见:Installing the Spring Boot CLI - 使用 IDE,这里以 STS 为例
- 右键选择【New】创建工程
- 选择【Spring Starter Project】
- 在弹出的窗口填入必要信息,点击【Next】
- 在依赖窗口选择必要的组件依赖,点击【Next】
- 随后出现压缩包 url 窗口,点击【Finish】即可创建新工程
配置 Spring Boot
-
配置文件路径
/app/src/main/resources/application.properties
-
可配置的属性大全
Spring Data JPA - 数据层
JPA 是什么
JPA ( Java Persistence API ) 是一个应用程序编程接口规范,该规范描述 Java 平台应用如何对关系型数据进行管理。其包含编程接口、Java 持久化查询语言(JPQL)及对象关系元数据三方面。
Spring Data JPA 是 Spring Data 体系的一部分,可以轻松实现基于 JPA 的存储库。该模块加强对基于 JPA 的数据访问层的支持。它使得构建基于 Spring 的数据访问技术应用程序更加简单。
添加 Spring Data JPA 支持
-
代码结构
io └── javabrains └── CourseApiDataApplication.java └── springbootstarter └── course │ └── Course.java │ └── CourseController.java │ └── CourseRepository.java │ └── CourseService.java └── topic └── Topic.java └── TopicController.java └── TopicRepository.java └── TopicService.java
一个 Topic 包含多个 Course,注意 CourseRepository 类中的关联查找,及所用到的 JPA 注解。
实现源代码:course-api-data
部署及监控
打包及运行 Spring Boot 应用
-
打包成可独立执行的 jar 文件
在终端 cd 到 Spring Boot 应用根目录,运行:
mvn clean install
将会把项目打包成可执行的 jar 文件:
target └── course-api-data-0.0.1-SNAPSHOT.jar └── course-api-data-0.0.1-SNAPSHOT.jar.original
执行如下命令即可部署及运行项目可执行 jar 文件:
java -jar target/course-api-data-0.0.1-SNAPSHOT.jar
-
打包成可部署到外部 Web 容器的 war 文件
将项目中 pom.xml 文件中的打包格式修改成 war:
<groupId>io.javabrains</groupId> <artifactId>course-api-data</artifactId> <version>0.0.1-SNAPSHOT</version> <!-- 此处修改为 war --> <packaging>war</packaging>
在终端 cd 到 Spring Boot 应用根目录,运行:
mvn clean install
将会把项目打包成可外部部署的 war 文件:
target └── course-api-data-0.0.1-SNAPSHOT.war └── course-api-data-0.0.1-SNAPSHOT.war.original
-
jar vs war 和 jar.original vs war.original
这两组压缩文件的目录结构区别,请查看:
注意:lib 目录中包含项目所依赖的 jar 包被故意省略了很多。
Spring Boot Actuator
Actuator 能够帮助监控及管理所关联的应用程序,通过在 pom.xml 中添加 actuator 组件:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
增加此模块后,就可以在相应端点查看应用信息,例如:
- /health - 查看当前应用健康信息
- /metrics - 显示当前应用的“指标”信息
- /trace - 显示跟踪信息(最后几个 http 请求)
例如:浏览器输入:
http://localhost:8080/health
将得到如下信息:
{
"status": "UP",
"diskSpace": {
"status": "UP",
"total": 249769230336,
"free": 74248032256,
"threshold": 10485760
},
"db": {
"status": "UP",
"database": "Apache Derby",
"hello": 1
}
}
当然还有很多端点可供配置,有些没有配置默认不显示信息,例如:/info
详细资料参见:spring-boot-actuators