Spring Boot 第一个应用程序
本节介绍如何开发一个小的可以突出 Spring Boot 的一些关键特性的 web 应用程序。 我们使用 Maven 来构建这个项目,因为大多数 IDE 都支持它。
在我们开始之前,打开一个终端并运行以下命令以确保安装了有效版本的 Java 和 Maven:
$ java -version
openjdk version "11.0.12" 2021-07-20
OpenJDK Runtime Environment Homebrew (build 11.0.12+0)
OpenJDK 64-Bit Server VM Homebrew (build 11.0.12+0, mixed mode)
$ mvn -v
Apache Maven 3.8.4 (9b656c72d54e5bacbed989b64718c159fe39b537)
Maven home: /Users/jiyik/apache-maven-3.8.4
Java version: 11.0.12, vendor: Homebrew, runtime: /usr/local/Cellar/openjdk@11/11.0.12/libexec/openjdk.jdk/Contents/Home
Default locale: en_CN, platform encoding: UTF-8
OS name: "mac os x", version: "10.14.5", arch: "x86_64", family: "mac"
注意
:此示例需要在其自己的目录中创建。 后续说明假定已经创建了一个合适的目录并且它是我们的当前目录。
创建 POM
首先我们使用 IDEA 创建一个 Maven 项目
填写 groupId 和 artifactId
然后进行下一步,最后点击完成。这样我们一个基本的 Maven 项目就创建完成了。
下面是一个基本的 Maven 项目结构
项目创建完成了,我们需要编辑 Maven pom.xml 文件。 pom.xml 是用于构建项目的配置文件。打开 pom.xml 添加如下内容
<?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>com.spring</groupId>
<artifactId>springBootProject</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.6</version>
</parent>
</project>
上面的配置知识给我们一个工作构建。 可以通过运行 mvn package
来测试
Spring Boot 提供了许多“启动器”,可让我们将 jars 添加到 classpath 中。 我们的冒烟测试(smoke test)应用程序使用 POM parent 部分中的 spring-boot-starter-parent
。 spring-boot-starter-parent
是一个特殊的启动器,它提供有用的 Maven 默认值。 它还提供了dependency-management
,以便我们可以省略“blessed”依赖项的 version
标签。
其他“启动器”为我们提供了在开发特定类型的应用程序时可能需要的依赖项。 由于我们正在开发 Web 应用程序,因此我们添加了 spring-boot-starter-web
依赖项。 在此之前,我们可以通过运行以下命令查看我们当前拥有的内容:
$ mvn dependency:tree
com.spring:springBootProject:jar:1.0-SNAPSHOT
mvn dependency:tree
命令打印项目依赖项的树形结构。 我们可以看到 spring-boot-starter-parent
本身不提供任何依赖项。 要添加必要的依赖项,需要编辑 pom.xml 并在 parent 部分的正下方添加 spring-boot-starter-web 依赖项:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
如果再次运行 mvn dependency:tree
,我们会看到现在有许多附加依赖项,包括 Tomcat Web 服务器和 Spring Boot 本身。
编写代码
为了完成我们的应用程序,我们需要创建一个 Java 文件。 默认情况下,Maven 从 src/main/java
编译源代码,因此我们先在该目录下新建一个 com.study 包。然后新建 MyApplication.java 文件并包含以下代码:
@RestController
@EnableAutoConfiguration
public class MyApplication {
@RequestMapping("/")
String home() {
return "Hello 迹忆客(jiyik.com)!";
}
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
虽然这里没有太多代码,但有很多事情正在发生。 我们将在接下来的几节中逐步介绍重要部分。
@RestController 和 @RequestMapping 注解
MyApplication 类的第一个注解是 @RestController
。 这称为构造型注释。 它为阅读代码的人和 Spring 提供了类扮演特定角色的提示。 在这种情况下,我们的类是一个 web @Controller
,所以 Spring 在处理传入的 web 请求时会考虑它。
@RequestMapping
注解提供“路由”信息。 它告诉 Spring 任何带有 /
路径的 HTTP 请求都应该映射到 home 方法。 @RestController
注解告诉 Spring 将结果字符串直接呈现给调用者。
提示
:@RestController 和 @RequestMapping 注解是 Spring MVC 注解(它们并不特定于 Spring Boot)。 有关详细信息,请参阅 Spring 参考文档中的 MVC 部分 。
@EnableAutoConfiguration 注解
第二个类级别的注解是 @EnableAutoConfiguration
。 这个注解告诉 Spring Boot 根据你添加的 jar 依赖来“猜测”你想如何配置 Spring。 由于 spring-boot-starter-web
添加了 Tomcat 和 Spring MVC,因此自动配置假定我们正在开发 Web 应用程序并相应地设置 Spring。
启动器和自动配置 : 自动配置旨在与“启动器”很好地配合使用,但这两个概念没有直接联系。 我们可以自由选择启动器之外的 jar 依赖项。 Spring Boot 仍然尽力自动配置我们的应用程序。
main 方法
我们应用程序的最后一部分是 main 方法。 这是一种遵循应用程序入口点的 Java 约定的标准方法。 我们的 main 方法通过调用 run 委托给 Spring Boot 的 SpringApplication
类。 SpringApplication 引导我们的应用程序,启动 Spring,然后启动自动配置的 Tomcat Web 服务器。 我们需要将 MyApplication.class
作为参数传递给 run 方法来告诉 SpringApplication 哪个是主要的 Spring 组件。 args
数组也被传递以公开任何命令行参数。
运行应用程序
此时,我们的应用程序应该可以工作了。使用 IDEA 来运行程序,点击右上角的运行按钮,启动结果如下所示
出现上面结果说明应用程序启动成功了。
如果我们打开浏览器访问 localhost:8080
,应该会看到以下输出:
或者我们也可以在项目根目录下运行下面的maven命令来运行程序
$ mvn spring-boot:run
创建 Jar 包
我们通过创建一个可以在生产中运行的完全独立的可执行 jar 文件来完成我们的示例。 可执行 jars(有时称为“fat jars”)是包含已编译类以及代码需要运行的所有 jar 依赖项的存档。
Java 不提供加载嵌套 jar 文件(本身包含在 jar 中的 jar 文件)的标准方法。 如果你希望分发一个独立的应用程序,这可能会出现问题。 为了解决这个问题,许多开发人员使用“uber” jars 。 一个 uber jar 将所有应用程序依赖项中的所有类打包到一个存档中。 这种方法的问题是很难看到应用程序中有哪些库。 如果在多个 jar 中使用相同的文件名(但内容不同),也可能会出现问题。 Spring Boot 采用了不同的方法,让你实际上可以直接嵌套 jar。
要创建一个可执行的 jar,我们需要将 spring-boot-maven-plugin
添加到我们的 pom.xml 中。 为此,请在依赖项部分下方插入以下行:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
注意
:spring-boot-starter-parent POM 包含 <executions> 配置以绑定 repackage goal 。 如果不使用 parent POM,则需要自己声明此配置。
保存 pom.xml 并从命令行运行 mvn package,如下所示:
$ mvn package
[INFO] Scanning for projects...
[INFO]
[INFO] --------------------< com.spring:springBootProject >--------------------
[INFO] Building springBootProject 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:3.2.0:resources (default-resources) @ springBootProject ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] Copying 0 resource
[INFO] Copying 0 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ springBootProject ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-resources-plugin:3.2.0:testResources (default-testResources) @ springBootProject ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] Using 'UTF-8' encoding to copy filtered properties files.
[INFO] skip non existing resourceDirectory /Users/jiyik/workspace/java/springBootProject/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ springBootProject ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.22.2:test (default-test) @ springBootProject ---
[INFO]
[INFO] --- maven-jar-plugin:3.2.2:jar (default-jar) @ springBootProject ---
[INFO] Building jar: /Users/jiyik/workspace/java/springBootProject/target/springBootProject-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.6.6:repackage (repackage) @ springBootProject ---
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.180 s
[INFO] Finished at: 2022-04-21T21:57:46+08:00
[INFO] ------------------------------------------------------------------------
[WARNING] The requested profile "test" could not be activated because it does not exist.
查看 target 目录,我们应该会看到 springBootProject-0.0.1-SNAPSHOT.jar
。 该文件的大小应约为 10 MB。 如果想看里面,可以使用jar tvf,如下:
$ jar tvf target/springBootProject-0.0.1-SNAPSHOT.jar
要运行该应用程序,需要使用 java -jar
命令,如下所示:
$ java -jar springBootProject-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.6.6)
2022-04-21 22:02:05.235 INFO 5030 --- [ main] com.study.MyApplication : Starting MyApplication v1.0-SNAPSHOT using Java 11.0.12 on 迹忆客 with PID 503