Spring Boot 让我们的 Spring 应用变的更轻量化,可以仅仅依靠一个 Java 类来运行一个 Spring 引用。你也可以打包你的应用为 jar 并通过使用 java -jar 命令来运行你的 Spring Web应用(这一点非常方便 dockerized)。而不需要从 servlet 开始一步步的写 xml 配置文件,而 Spring Boot 的提供的各种 starter 更是会自动配置,避免了各种繁琐的 xml 文件的编写,方便了各种模块的快速集成。

通常的,Java Web 开发中会设计到两个组合框架:SSH 和 SSM;SSH 通常指的是 Struts2 做控制器(controller),Spring 管理各层的组件,Hibernate 负责持久化层。SSM 则指的是 SpringMVC 做控制器(controller),Spring 管理各层的组件,MyBatis 负责持久化层。而 Spring boot 可以算是新出的 Java Web 方式,其特性可以参考 SpringBoot2.0完整参考文档,下文将会以如何快速搭建起一个 Spring Boot 应用,来阐述 Spring Boot 的特性。

创建一个 spring boot 项目

搭建一个 Spring Boot 项目有多种方法。

在线生成器

可以从 SPRING INITIALIZR 网站上选择参数和依赖包,生成基础的项目,然后打包下载下来,之后使用 IDEA 从已有文件夹中打开,注意勾选上 Import project from external model

IDEA

IDEA 在新建项目的界面集成了 Spring Initializr ,可以直接通过这个完成基础项目的创建。

VScode

在 VScode 上也可以通过安装 Spring Initializr Java Support 插件来完成基础 Spring Boot 项目的创建。

Maven

也可以在 IDEA 里创建一个空 maven 工程, pom.xml 里添加:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>1.5.6.RELEASE</version>
    </dependency>
</dependencies>

对于已有自定义的 parent pom,可以参见 using-boot-maven-without-a-parent 解决。

以 maven 的空工程创建为例,创建 src/main/java/Demo/DemoApplication.java 文件,其内容如下:

1
2
3
4
5
6
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

编写一个 src/main/java/Demo/controller/HelloController.java,会发现这里的 @Controller 就是 Spring 里的声明 Bean 的注解。

1
2
3
4
5
6
7
8
@Controller
public class HelloController {
    @RequestMapping("/hello")
    @ResponseBody
    public String hello() {
        return "Hello Spring Boot !!!";
    }
}

可以用使用结合了 @Controller@ResponseBody 注解的 @RestController,使得 REST 接口风格的代码简化(Spring MVC)

1
2
3
4
5
6
7
@RestController
public class HelloController {
    @RequestMapping("/hello")
    public String hello() {
        return "Hello Spring Boot !!!";
    }
}

之后 IDEA 应该就能够自动发现工程为 Spring Boot,运行之后,在浏览器里访问 localhost:8080/hello 即可得到返回。但是对比生成器生成的项目,会发现 pom.xml 里少了下面的内容。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

这些依赖的作用分别为:

  • spring-boot-starter:核心模块,包括自动配置支持、日志和 YAML。

  • spring-boot-starter-test:测试模块,包括 JUnit、Hamcrest、Mockito。

  • spring-boot-maven-plugin 该插件提供下面的功能:

    • 搜索 public static void main() 并标记为可运行类
    • 可以用于 maven 命令打包 Spring boot 项目成 jar 包
    • 内置依赖解析,自动选择当前 Spring boot 合适的依赖版本

单元测试

加上上面提到的单元测试的依赖,并在 src/test/java/Demo/controller/HelloControllerTests.java 编写下面的内容用于单元测试并运行单元测试。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {

    private MockMvc mvc;

    @Autowired
    private HelloController helloController;

    @Before
    public void setUp() throws Exception {
        mvc = MockMvcBuilders.standaloneSetup(helloController).build();
    }

    @Test
    public void getHello() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/hello")
                .accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().string("Hello Spring Boot !!!"));
    }
}

或者使用 @AutoConfigureMockMvc 注解依赖注入的方式获取 mvc ,而不是手动生成。

1
2
3
4
5
6
7
8
9
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerTests {
    @Autowired
    private MockMvc mvc;

    ...
}

也可以使用 TestRestTemplate 进行接口测试。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloControllerIT {

    @LocalServerPort
    private int port;

    private URL base;

    @Autowired
    private TestRestTemplate template;

    @Before
    public void setUp() throws Exception {
        this.base = new URL("http://localhost:" + port + "/hello");
    }

    @Test
    public void getHello() throws Exception {
        ResponseEntity<String> response = template.getForEntity(base.toString(),
                String.class);
        assertThat(response.getBody(), equalTo("Hello Spring Boot !!!"));
    }
}

除此之外,对比生成器生成的工程会少了 src/main/resources/application.properties 文件,该文件可以控制 spring boot 的很多配置,也可以运行用户自定义配置,如想更改 Spring Boot 启动时候绑定的端口可以这样配置

1
server.port=8081

更多的配置可参考 common-application-properties

配置中的 ${VAL} 既可以是 properties 中的键,也可以是 System.getProperty 方法得到的即 JVM 的参数(java -Dkey=value),也可以是 System.getEnv 得到的环境变量。或者是 spring 特有的通过 java -jar xxx.jar --key=value 的方式,如果有以上三种方式传入的 key 和配置里面重复,会以传入参数为准,更多参见Externalized Configuration

便捷开发

为了方便平时的开发,通常还会做如下的事情。

maven-plugin

安装 spring-boot-maven-plugin 可以提供打包、运行、测试。

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>

之后就可以使用命令 mvn spring-boot:run 运行项目。

devtools

开发工具可以很方便的自动检测编译后文件、classpath 的改动,然后重启(这一点和 Django 开发很像),添加依赖。

1
2
3
4
5
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
</dependency>

如果在修改了代码或者配置文件之后需要触发自动加载的话,在 IDEA 中可以使用 Build -> Build Project (Ctrl + F9) 来触发一次编译,然后就可以随即触发 devtools 的自动加载。

也可以设置 IDEA 自动编译来触发:

  1. 打开编译设置 Settings -> Build, Execution, Deployment -> Compiler 然后能使 Build project automatically 选项。
  2. Shift+Ctrl+Alt+/ 选择 Registry 之后能使 compiler.automake.allow.when.app.running 和 ide.windowSystem.autoShowProcessPopup。
  3. 重启项目

IDEA 本身是自动保存文件,加上自动编译有可能会造成一点困惑。我的建议还是使用手动来触发,会比直接使用 IDEA 里面的 Rerun 会快一点。

同时该工具还可以运行远程应用,有兴趣可以自行探索。

参考