Bootstrap

用Spring Initializr快速构建SpringBoot及整合MVC

给岁月以文明,而不是给文明以岁月。

前言

用Spring Initializr创建SpringBoot工程虽然方便,但是得有网耗时耗流量,而且默认下载最新版本(强迫症可能会不舒服),网络不佳时还可能下载半天然后失败,如:
在这里插入图片描述
不想这样的话,可以参考我的这篇博客,用maven工程构建包括如何同时启动多个SpringBoot工程实例如何用Maven搭建一个SpringBoot工程

后语

时代变得真快呀,现在SpingBoot官方直接强推Java17,然而现在很多企业还是用Java8

在这里插入图片描述
如果还想使用Spring Initializr快速构建的话,需要点击Server URL那一栏的设置按钮,进行换源,换成: https://start.aliyun.com
在这里插入图片描述
然后点击OK,就OK啦:
在这里插入图片描述

二步搭建

1.打开"IDEA",选择"Create New Project" -> “Next”,填写组织名,如"com.guqueyue"; 项目名,如"hello_guqueyue",再点击"Next",下一步。
在这里插入图片描述
2.此处我们勾选"Spring MVC"的核心依赖,开启web功能:点击 “Web” -> “Spring Web”,再点击"Next",确认项目放置位置,再点击"Finish",等待IDEA右下方的进度条显示下载完成,即可。
在这里插入图片描述

项目结构

选中application.properties文件,右键 -> “Refactor” -> “Rename…” ,再点击"Refactor"后,重命名为application.yml后,项目结构图如下:
在这里插入图片描述
其中配置文件pom.xml中有spring-boot-starter-webspring-boot-starter-test的起步依赖:
在这里插入图片描述
代码如下:

	<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>
            <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
        </dependency>
    </dependencies>

其中,spring-boot-starter-web是web功能的起步依赖,它会自动导入与web相关的依赖;spring-boot-starter-test为SpringBoot测试功能的起步依赖,它会自动导入与SpringBoot测试相关的依赖,通过依赖继承关系图可以很容易看出:
在这里插入图片描述
在工程代码包的主目录下有一个名为HelloGuqueyueApplication的类,该类是程序的启动类,代码如下:

@SpringBootApplication
public class HelloGuqueyueApplication {

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

}

其中,@SpringBootApplication为SpringBoot的核心注解,该注解包含@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan三个注解,开启了包扫描、配置和自动配置的功能。
在这里插入图片描述

构建Web

建立一个Web层的Controller,如:

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String hello() {
        return "Hello, guqueyue!";
    }

}

在这里插入图片描述
其中@RestController注解表明这个类是一个RestControlletr。@RestController是Spring4.0版本的一个注解,它的功能相当于@Controller@ResponseBody两个注解之和,点进去一看便知:
在这里插入图片描述
@RequestMapping则是配置请求地址的Url映射.

现在controller已经编写好了,那么SpringBoot如何找到这个Controller?
↓ 预知后事如何,请看下回分解 ↓

@Import注解

在启动类上,用@Import注解导入Controller的反射对象:

@Import(HelloController.class)

在这里插入图片描述
那么,问题来了,如果有多个Controller怎么办?
在这里插入图片描述
点开@Import注解一看,发现value里面为一个反射对象数组,因此可以这样:

@Import({HelloController.class, OtherController.class...})
可是还有一个问题,万一有几百个Controller,还需要一个一个写吗?

@SpringBootApplication注解

当然不是!可以通过SpringBoot的核心注解@SpringBootApplication,配置扫描路径。当然@SpringBootApplication的默认扫描路径,是从启动类的包下,逐层扫描。如果我们的Controller没有和启动类在一个包下则需要用@Import注解导入或者自行配置扫描路径,如:

@SpringBootApplication(scanBasePackages = "com.guqueyue")

在这里插入图片描述
点开@SpringBootApplication一看,scanBasePackages()支持字符串数组,
在这里插入图片描述因此我们也可以同时配置多个扫描路径,如:

@SpringBootApplication(scanBasePackages = {"com.guqueyue", "com.other"...})

找到Tomcat

找到启动类,运行main方法,启动SpringBoot程序。再打开浏览器,在浏览器上输入"http://localhost:8080/hello",浏览器上会显示"Hello, guqueyue!"
在这里插入图片描述
其中8080为SpringBoot程序的默认端口。如果需要,可以在配置文件application.yml中自定义端口,如8762:

server:
  port: 8762

可能这里有人会有疑问了,Tomcat去哪儿呢?之前我们运行Web程序,不是把Web工程打成war包,然后放到Tomcat容器中运行,之后再通过浏览器访问的吗?如果有细心的小伙伴可能之前就发现了,Web功能的起步依赖spring-boot-starter-web中已经自动导入了一个叫spring-boot-starter-tomcat的依赖,SpringBoot反向整合了Tomcat服务,也就是说它会通过Tomcat的插件,在SpringBoot运行时自动运行Tomcat。在这里插入图片描述

开启测试功能

SpringBoot开启测试功能也十分的简单,只需要在测试类上加@RunWith(SpringRunner.class)@SpringBootTest两个注解即可

如果使用Spring Initializr搭建工程的话先去除SpringBoot测试起步依赖spring-boot-starter-test排除依赖;用maven搭建工程的话,请先添加SpringBoot测试起步依赖spring-boot-starter-test

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope><!-- 该依赖仅仅参与测试相关的工作 -->
</dependency>

再在src/test/java/com/guqueyue/hello_guqueyue目录下, 创建一个名为TestApplication的测试类,如:

/**
 * @author guqueyue
 * @Date 2020/4/19
 **/
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestApplication {

    @Test
    public void test() {
        System.out.println("这是一个测试方法");
    }
}

运行test()方法,一道绿光闪过,控制台输出:
在这里插入图片描述
说明test()运行成功,接着我们可以测试一下之前的controller,再在相同的目录下创建一个HelloController的测试类,代码如下:

package com.guqueyue.hello_guqueyue.controller;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;

import java.net.URL;

import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;

@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() {
        ResponseEntity<String> response = template.getForEntity(base.toString(), String.class);
        assertThat(response.getBody(), equalTo("Hello, guqueyue!"));
    }

}

其中@SpringBootTest注解加上了Web测试环境端口为随机端口的配置,RestTemplate用于远程调用Http API接口,而TestRestTemplate为RestTemplate的测试类(千万不要导错包),运行添加了 @Test注解的getHello()方法:
在这里插入图片描述
如果你看到控制台一道绿光闪过,这就说明的测试通过(^_−)☆

;