1. IDEA创建Spring Boot项目

1.1 配置开发环境

在使用 Spring Boot 进行开发之前,第一件事就是配置好开发环境。这里我们以 Windows 操作系统为例,如果您使用的是其他操作系统,请对照其相关设置进行操作。

工欲善其事,必先利其器,IDE(集成开发环境)的选择相当重要,目前市面上有很多优秀的 IDE 开发工具,例如 IntelliJ IDEA、Spring Tools、Visual Studio Code 和 Eclipse 等等,那么我们该如何选择呢?

这里我们极力推荐大家使用 IntelliJ IDEA,因为相比于与其他 IDE,IntelliJ IDEA 对 Spring Boot 提供了更好的支持。

Spring Boot 版本及其环境配置要求如下表。

Spring Boot 2.x
JDK 8.0 及以上版本
Maven 3.x
IntelliJ IDEA 14.0 以上

1.2创建 Spring Boot 项目

开发环境配置完成后,接下来,我们就可以通过 Intellij IDEA 创建一个 Spring Boot 项目了。

Intellij IDEA 一般可以通过两种方式创建 Spring Boot 项目:

  • 使用 Maven 创建
  • 使用 Spring Initializr 创建

1.2.1 使用 Maven 创建

  1. 使用 IntelliJ IDEA 创建一个名称为 helloworld 的 Maven 项目,创建过程请参考 IDEA 新建 Maven 项目

  2. 在该 Maven 项目的 pom.xml 中添加以下配置,导入 Spring Boot 相关的依赖。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<project>
...
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
...
</project>
  1. 在 net.biancheng.www 包下,创建一个名为 helloWorldApplication 主程序,用来启动 Spring Boot 应用,代码如下。
1
2
3
4
5
6
7
8
9
package net.biancheng.www;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class helloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(helloWorldApplication.class, args);
}
}

Spring Boot 项目目录结构如下图。

Spring Boot 目录结构

图1:Spring Boot 项目结构

1.2.2 使用 Spring Initializr 创建

IntelliJ IDEA 支持用户使用 Spring 项目创建向导(Spring Initializr )快速地创建一个 Spring Boot 项目,步骤如下。

  1. 在 IntelliJ IDEA 欢迎页面左侧选择 Project ,然后在右侧选择 New Project,如下图。

IDEA 欢迎页面

图2:IDEA 欢迎页面新建项目

或者在 IntelliJ IDEA 工作区上方的菜单栏中选择 File ,在下拉菜单中选则 New,然后选择 Project,如下图。

IDEA 新建Maven 项目1

图3:IDEA 工作区 新建 Maven 项目

  1. 在新建工程界面左侧,选择 Spring Initializr,选择项目的 SDK 为 1.8,选择 starter service URL 为 http://start.spring.io(默认),最后点击下方的 Next 按钮进行下一步。

initralizr
图4:Spring Intializr 创建向导

  1. IDEA 会连接网络,并根据 starter service URL 查询 Spring Boot 的当前可用版本和组件列表,如下图。

IDEA 联网查询 Springboot 可以用版本及组件列表
图5:IDEA 联网查询 Springboot 可以用版本及组件列表

  1. 在 Spring Initializr Project Settings 中,输入项目的 GroupId、ArtifactId 等内容,注意 Type 为 Maven,packaging 为 jar,Java version 切换为 8(默认为 11),最后点击下方的 Next 按钮,进行下一步。

Spring Boot Initializr Settings
图6:Spring Boot Initializr Settings

  1. 在 dependencise 界面中,选择 Spring Boot 的版本及所依赖的 Spring Boot 组件(例如 Spring Boot 的版本为 2.4.5, Spring Boot 组件为 Web),然后点击下方的 Next 按钮。

IDEA 组件选择和版本切换
图7:Spring Boot 组件和版本选择

  1. 根据需要修改项目名称及项目存储位置等信息,最后点击 Finish 按钮,完成 Spring Boot 项目的创建,如下图。

img
图8:Initializr 完成创建 Spring Boot 项目

  1. 返回 IDEA 工作区,可以看到 Spring Boot 项目 helloworld 已经创建完成。该项目不但具有完整的目录结构,还有完整的 Maven 配置,并默认生成了一个名为 HelloworldApplication 的主启动程序。

Spring Boot 目录结构

图9:Spring Boot 项目结构

此时,几乎所有的准备工作都已经准备就绪,我们可以在没有编写任何代码的情况下,直接将该 Spring Boot 项目运行起来。

1.3 启动 Spring Boot

默认情况下,Spring Boot 项目会创建一个名为 ***Application 的主程序启动类 ,该类中使用了一个组合注解 @SpringBootApplication,用来开启 Spring Boot 的自动配置,另外该启动类中包含一个 main() 方法,用来启动该项目。

直接运行启动类 HelloworldApplication 中的 main() 方法,便可以启动该项目,结果如下图。

Spring Boot helloworld
图10:Spring Boot 项目 helloWorld 运行日志

注意:Spring Boot 内部集成了 Tomcat,不需要人为手动配置 Tomcat,开发者只需要关注具体的业务逻辑即可。

为了能比较的清楚的看到效果,我们在 net.biancheng.www 包下又创建一个 controller 包,并在该包内创建一个名为 HelloController 的 Controller,代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
package net.biancheng.www.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@ResponseBody
@RequestMapping("/hello")
public String hello() {
return "Hello World!";
}
}

重启 Spring Boot 项目,然后在地址栏访问 “http://localhost:8080/hello”,结果如下图。

img
图11:Spring Boot 项目 helloWorld 访问结果

2. Spring Boot starter

传统的 Spring 项目想要运行,不仅需要导入各种依赖,还要对各种 XML 配置文件进行配置,十分繁琐,但 Spring Boot 项目在创建完成后,即使不编写任何代码,不进行任何配置也能够直接运行,这都要归功于 Spring Boot 的 starter 机制。本节我们将对 stater 进行介绍。

2.1 starter

Spring Boot 将日常企业应用研发中的各种场景都抽取出来,做成一个个的 starter(启动器),starter 中整合了该场景下各种可能用到的依赖,用户只需要在 Maven 中引入 starter 依赖,SpringBoot 就能自动扫描到要加载的信息并启动相应的默认配置。starter 提供了大量的自动配置,让用户摆脱了处理各种依赖和配置的困扰。所有这些 starter 都遵循着约定成俗的默认配置,并允许用户调整这些配置,即遵循“约定大于配置”的原则。

并不是所有的 starter 都是由 Spring Boot 官方提供的,也有部分 starter 是第三方技术厂商提供的,例如 druid-spring-boot-starter 和 mybatis-spring-boot-starter 等等。当然也存在个别第三方技术,Spring Boot 官方没提供 starter,第三方技术厂商也没有提供 starter。

以 spring-boot-starter-web 为例,它能够为提供 Web 开发场景所需要的几乎所有依赖,因此在使用 Spring Boot 开发 Web 项目时,只需要引入该 Starter 即可,而不需要额外导入 Web 服务器和其他的 Web 依赖。

在 pom.xml 中引入 spring-boot-starter-web,示例代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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>
<!--SpringBoot父项目依赖管理-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/>
</parent>
....
<dependencies>
<!--导入 spring-boot-starter-web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
...
</dependencies>
...
</project>

在该项目中执行以下 mvn 命令查看器依赖树。

1
mvn dependency:tree

执行结果如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
[INFO] Scanning for projects...
[INFO]
[INFO] --------------------< net.biancheng.www:helloworld >--------------------
[INFO] Building helloworld 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:3.1.2:tree (default-cli) @ helloworld ---
[INFO] net.biancheng.www:helloworld:jar:0.0.1-SNAPSHOT
[INFO] \- org.springframework.boot:spring-boot-starter-web:jar:2.4.5:compile
[INFO] site.shaoshao:spring-init:jar:0.0.1-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.6.3:compile
[INFO] | +- org.springframework.boot:spring-boot-starter:jar:2.6.3:compile
[INFO] | | +- org.springframework.boot:spring-boot:jar:2.6.3:compile
[INFO] | | +- org.springframework.boot:spring-boot-autoconfigure:jar:2.6.3:compile
[INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:2.6.3:compile
[INFO] | | | +- ch.qos.logback:logback-classic:jar:1.2.10:compile
[INFO] | | | | \- ch.qos.logback:logback-core:jar:1.2.10:compile
[INFO] | | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.17.1:compile
[INFO] | | | | \- org.apache.logging.log4j:log4j-api:jar:2.17.1:compile
[INFO] | | | \- org.slf4j:jul-to-slf4j:jar:1.7.33:compile
[INFO] | | +- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile
[INFO] | | \- org.yaml:snakeyaml:jar:1.29:compile
[INFO] | +- org.springframework.boot:spring-boot-starter-json:jar:2.6.3:compile
[INFO] | | +- com.fasterxml.jackson.core:jackson-databind:jar:2.13.1:compile
[INFO] | | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.13.1:compile
[INFO] | | | \- com.fasterxml.jackson.core:jackson-core:jar:2.13.1:compile
[INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.13.1:compile
[INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.13.1:compile
[INFO] | | \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.13.1:compile
[INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.6.3:compile
[INFO] | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.56:compile
[INFO] | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.56:compile
[INFO] | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.56:compile
[INFO] | +- org.springframework:spring-web:jar:5.3.15:compile
[INFO] | | \- org.springframework:spring-beans:jar:5.3.15:compile
[INFO] | \- org.springframework:spring-webmvc:jar:5.3.15:compile
[INFO] | +- org.springframework:spring-aop:jar:5.3.15:compile
[INFO] | +- org.springframework:spring-context:jar:5.3.15:compile
[INFO] | \- org.springframework:spring-expression:jar:5.3.15:compile
[INFO] \- org.springframework.boot:spring-boot-starter-test:jar:2.6.3:test
[INFO] +- org.springframework.boot:spring-boot-test:jar:2.6.3:test
[INFO] +- org.springframework.boot:spring-boot-test-autoconfigure:jar:2.6.3:test
[INFO] +- com.jayway.jsonpath:json-path:jar:2.6.0:test
[INFO] | +- net.minidev:json-smart:jar:2.4.7:test
[INFO] | | \- net.minidev:accessors-smart:jar:2.4.7:test
[INFO] | | \- org.ow2.asm:asm:jar:9.1:test
[INFO] | \- org.slf4j:slf4j-api:jar:1.7.33:compile
[INFO] +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.3:test
[INFO] | \- jakarta.activation:jakarta.activation-api:jar:1.2.2:test
[INFO] +- org.assertj:assertj-core:jar:3.21.0:test
[INFO] +- org.hamcrest:hamcrest:jar:2.2:test
[INFO] +- org.junit.jupiter:junit-jupiter:jar:5.8.2:test
[INFO] | +- org.junit.jupiter:junit-jupiter-api:jar:5.8.2:test
[INFO] | | +- org.opentest4j:opentest4j:jar:1.2.0:test
[INFO] | | +- org.junit.platform:junit-platform-commons:jar:1.8.2:test
[INFO] | | \- org.apiguardian:apiguardian-api:jar:1.1.2:test
[INFO] | +- org.junit.jupiter:junit-jupiter-params:jar:5.8.2:test
[INFO] | \- org.junit.jupiter:junit-jupiter-engine:jar:5.8.2:test
[INFO] | \- org.junit.platform:junit-platform-engine:jar:1.8.2:test
[INFO] +- org.mockito:mockito-core:jar:4.0.0:test
[INFO] | +- net.bytebuddy:byte-buddy:jar:1.11.22:test
[INFO] | +- net.bytebuddy:byte-buddy-agent:jar:1.11.22:test
[INFO] | \- org.objenesis:objenesis:jar:3.2:test
[INFO] +- org.mockito:mockito-junit-jupiter:jar:4.0.0:test
[INFO] +- org.skyscreamer:jsonassert:jar:1.5.0:test
[INFO] | \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test
[INFO] +- org.springframework:spring-core:jar:5.3.15:compile
[INFO] | \- org.springframework:spring-jcl:jar:5.3.15:compile
[INFO] +- org.springframework:spring-test:jar:5.3.15:test
[INFO] \- org.xmlunit:xmlunit-core:jar:2.8.4:test
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15.492 s
[INFO] Finished at: 2022-02-10T11:50:44+08:00
[INFO] ------------------------------------------------------------------------

从以上结果中,我们可以看到 Spring Boot 导入了 springframework、logging、jackson 以及 Tomcat 等依赖,而这些正是我们在开发 Web 项目时所需要的。

您可能会发现一个问题,即在以上 pom.xml 的配置中,引入依赖 spring-boot-starter-web 时,并没有指明其版本(version),但在依赖树中,我们却看到所有的依赖都具有版本信息,那么这些版本信息是在哪里控制的呢?

其实,这些版本信息是由 spring-boot-starter-parent(版本仲裁中心) 统一控制的。

2.2 spring-boot-starter-parent

spring-boot-starter-parent 是所有 Spring Boot 项目的父级依赖,它被称为 Spring Boot 的版本仲裁中心,可以对项目内的部分常用依赖进行统一管理。

1
2
3
4
5
6
7
<!--SpringBoot父项目依赖管理-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.5</version>
<relativePath/>
</parent>

Spring Boot 项目可以通过继承 spring-boot-starter-parent 来获得一些合理的默认配置,它主要提供了以下特性:

  • 默认 JDK 版本(Java 8)
  • 默认字符集(UTF-8)
  • 依赖管理功能
  • 资源过滤
  • 默认插件配置
  • 识别 application.properties 和 application.yml 类型的配置文件

查看 spring-boot-starter- parent 的底层代码,可以发现其有一个父级依赖 spring-boot-dependencies。

1
2
3
4
5
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.5</version>
</parent>

spring-boot-dependencies 的底层代码如下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.4.5</version>
<packaging>pom</packaging>
....
<properties>
<activemq.version>5.16.1</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.88</appengine-sdk.version>
<artemis.version>2.15.0</artemis.version>
<aspectj.version>1.9.6</aspectj.version>
<assertj.version>3.18.1</assertj.version>
<atomikos.version>4.0.6</atomikos.version>
....
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-amqp</artifactId>
<version>${activemq.version}</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-blueprint</artifactId>
<version>${activemq.version}</version>
</dependency>
...
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>${build-helper-maven-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>${flyway.version}</version>
</plugin>
...
</plugins>
</pluginManagement>
</build>
</project>

以上配置中,部分元素说明如下:

  • dependencyManagement :负责管理依赖;
  • pluginManagement:负责管理插件;
  • properties:负责定义依赖或插件的版本号。

spring-boot-dependencies 通过 dependencyManagement 、pluginManagement 和 properties 等元素对一些常用技术框架的依赖或插件进行了统一版本管理,例如 Activemq、Spring、Tomcat 等。
��。