04.开发你的第一个SpringBoot应用

本节主要内容是如何通过开发一个简单的”Hello World!” web应用突出Spring Boot 的一些关键特性。 我们使用 Maven 来构建这个项目,因为大多数 IDE 都支持它。

spring.io 网站包含了许多使用 Spring Boot 的”入门”指南。 如果你需要解决一个特定的问题,首先检查那里。

通过访问 start.spring.io 并从依赖项查询中选择”Web”starter,可以快捷地完成以下步骤。 这样做会生成一个新的项目结构,以便您可以立即开始编码。 查看 Spring Initializr 文档了解更多细节。

在我们开始之前,打开一个终端并运行以下命令,以确保你已经安装了 Java 和 Maven 的有效版本:

1
2
3
4
$ java -version
java version "1.8.0_102"
Java(TM) SE Runtime Environment (build 1.8.0_102-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.102-b14, mixed mode)
1
2
3
4
$ mvn -v
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-17T14:33:14-04:00)
Maven home: /usr/local/Cellar/maven/3.3.9/libexec
Java version: 1.8.0_102, vendor: Oracle Corporation

这个示例需要在它自己的文件夹中创建。 接下来的介绍假设你已经创建了一个合适的文件夹,并且这个文件夹就是你的工作目录。

创建 POM 文件

我们首先需要创建一个 Maven pom.xml 文件。pom.xml 是用于构建项目的配方。 打开文本编辑器,添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.example</groupId>
<artifactId>myproject</artifactId>
<version>0.0.1-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>

<!-- Additional lines to be added here... -->

</project>

pom.xml 文件会为您提供一个工作构建。 您可以通过运行 mvn package 来测试它(现在,您可以先忽略 “jar will be empty - no content was marked for inclusion!” 的警告)。

现在,您可以将项目导入到 IDE 中(大多数Java IDE 都包含对 Maven 的内置支持)。 为了简单起见,我们继续使用纯文本编辑器。

添加 Classpath 依赖

Spring Boot 提供了很多 “Starter”,你可以将这些 jar 包添加到 classpath 中。在本例中,我们已经在 POM 文件的 parent 标签中使用了 spring-boot-starter-parentspring-boot-starter-parent 是一个特殊的 Starter,它提供了一些有用的Maven的默认值。同时也提供了一个 dependency-management 标签,这些你可以省略部分依赖的 version 标记。

其他 “Starter” 提供了在开发特定类型的应用程序时可能需要的依赖项。 因为我们正在开发一个 web 应用程序,所以我们添加了一个 spring-boot-starter-web 依赖项。 在此之前,我们可以通过运行以下命令查看我们当前已有的内容:

1
2
3
$ mvn dependency:tree

[INFO] com.example:myproject:jar:0.0.1-SNAPSHOT

mvn dependency:tree 命令以树的形式展示当前项目的依赖项。 您可以看到,spring-boot-starter-parent 本身并不提供任何依赖性。 要添加必要的依赖项,请编辑 pom.xml 并在 <parent> 节点下面添加 spring-boot-starter-web 依赖项:

1
2
3
4
5
6
<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 下编译源代码,因此需要创建该文件夹结构,然后添加一个名为 src/main/java/Examole.java 的文件,该文件内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.web.bind.annotation.*;

@RestController
@EnableAutoConfiguration
public class Example {

@RequestMapping("/")
String home() {
return "Hello World!";
}

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

}

虽然这里没有很多代码,但是有很多事情正在进行。 在接下来的几节中,我们将逐步介绍重要的部分。

@RestController 和 @RequestMapping 注解

Example 类的第一个注解是 @RestController。 这是一个称为 stereotype 注解。 它为阅读代码的人提供了提示;对 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。

Starter 和 自动装配

自动装配被设计成与”Starter”一起工作,但是这两个概念并没有直接联系在一起。 您可以在 Starter 之外自由选择 jar 依赖项。 Spring Boot 仍然尽最大努力自动配置应用程序。

“main” 方法

我们应用的最后一部分是 main 方法。 这只是遵循 Java 约定的应用程序入口点的标准方法。 我们的主方法委托给Spring Boot 的 SpringApplication 类,通过调用 run 来实现。 SpringApplication 启动我们的应用程序,启动 Spring,然后启动自动配置的 Tomcat web 服务器。 我们需要将 Example.class 作为参数传递给 run 方法,以告诉 SpringApplication 哪个是主 Spring 组件。 args 数组暴露出来以接收命令行参数。

运行示例

此时,您的应用程序应该可以工作了。 由于使用了 spring-boot-starter-parent POM,因此可以使用一个有用的 run 目标来启动应用程序。 输入 mvn spring-boot:run 从根项目目录启动应用程序。 你应该看到类似下面的输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ mvn spring-boot:run

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.5.RELEASE)
....... . . .
....... . . . (log output here)
....... . . .
........ Started Example in 2.222 seconds (JVM running for 6.514)

打开web 浏览器访问 localhost: 8080,可以看到如下输出:

1
Hello World!

可以按 ctrl-c退出应用程序。

创建一个可执行 Jar

我们通过创建一个完全自包含的可执行 jar 文件来完成示例,该文件可以在生产环境中运行。 可执行的 jar (有时称为”fat jars”)是存档文件,其中包含您编译的类以及您的代码需要运行的所有 jar 依赖项。

可执行的 jar 和 Java
Java 没有提供加载嵌套 jar 文件(jar 文件本身包含在 jar 中)的标准方法。 如果您希望分发一个自包含的应用程序,这可能会有问题。
为了解决这个问题,许多开发人员使用”超级”罐子(uber jar)。 一个 uber jar 将应用程序的所有依赖项的所有类打包到一个归档文件中。这种方法的问题在于,很难看到应用程序中有哪些库。如果在多个 jar 中使用相同的文件名(但内容不同) ,也会出现问题。
Spring Boot 采用了一种不同的方法,它可以让您直接嵌套 jar。

要创建一个可执行的 jar,我们需要将 spring-boot-maven-plugin 添加到 pom.xml 中。 为此,在 dependencies 部分下面插入以下行:

1
2
3
4
5
6
7
8
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

spring-boot-starter-parent POM 包括 <executions> 配置用于绑定 repackage 目标。 如果不使用父 POM,则需要自己声明此配置。 有关详细信息,请参阅插件文档

保存 pom.xml 并从命令行运行 mvn package,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ mvn package

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building myproject 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] .... ..
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ myproject ---
[INFO] Building jar: /Users/developer/example/spring-boot-example/target/myproject-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.1.5.RELEASE:repackage (default) @ myproject ---
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

如果查看 target 目录,应该会看到 myproject-0.0.1-SNAPSHOT.jar。 文件大小应该在10MB 左右。 如果你想查看jar 包内部的信息,你可以使用 jar tvf,如下所示:

1
$ jar tvf target/myproject-0.0.1-SNAPSHOT.jar

target 目录下,您还应该看到一个更小的文件,名为 myproject-0.0.1-SNAPSHOT.jar.original。 这是 Maven 在被 Spring Boot 重新打包之前创建的原始 jar 文件。

要运行该应用程序,请使用 java-jar 命令,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ java -jar target/myproject-0.0.1-SNAPSHOT.jar

. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.5.RELEASE)
....... . . .
....... . . . (log output here)
....... . . .
........ Started Example in 2.536 seconds (JVM running for 2.864)

可以按ctrl-c 退出应用程序。