简介

SpringBoot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化 Spring 应用的初始搭建以及开发过程。

SpringBoot开发分为如下几步:

  • 创建新模块,选择Spring初始化,并配置模块相关基础信息。
  • 选择当前模块需要使用的技术集。
  • 开发控制器类。
  • 运行自动生成的Application类。

SpringBoot有两个机制:

  • 依赖管理机制。
  • 自动配置机制。

项目创建及配置

创建项目

注意:

  1. 在创建好的工程中不需要创建配置类。

  2. 创建好的项目会自动生成其他的一些文件(这些文件目前来说没有任何作用),可以将这些文件删除。

    可以删除的目录和文件如下:

    • .mvn
    • .gitignore
    • HELP.md
    • mvnw
    • mvnw.cmd

项目依赖

在项目中的pom.xml中有如下代码:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.5</version>
    <!-- 这里的版本被修改过,按照上方创建的工程版本应该是 3.0.3 -->
    <relativePath/> <!-- lookup parent from repository -->
</parent>

该代码指定了一个父工程,父工程中的东西在该工程中可以继承过来使用。

并且使用Spring Initializr创建的项目会自动在pom.xml中导入所需的起步依赖(包含starter的依赖)。

pom.xml中还有如下起步依赖:

<dependencies>

    <!-- Springboot Web 开发所需的起步依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Springboot 整合Junit的起步依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

</dependencies>

引导类

创建的每个SpringBoot项目都包含一个引导类,如:

@SpringBootApplication
public class SpringbootDemoApplication {

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

}

引导类是项目的入口,运行main()就可以启动项目。

引导类默认只会扫描当前包下同级的类和包(包下的的类)。

如果Controller包与引导类的包同级(例如com.linner.controllercom.linner.springbootdemo),此时引导类可以正常启动,但是由于扫描不到Cotroller包,接口无法访问。有三种解决方法:

  1. 将Controller包移动到引导类的包下(此处为springbootdemo)。

  2. 将引导类移动到项目组包下(此处为com.linner)。

  3. 在创建工程时,修改软件包名。

    Spring Initializr默认软件包名为项目组名.项目名(此处为com.linner.springbootdemo)。此处创建的项目将其修改为项目组名(com.linner)。

SpringApplication.run(...) 的返回值是当前项目的ApplicationContext

切换 Web 服务器

如果要使用Jetty服务器,我们需要先在pom.xml中使用<exclusion>标签排除默认的Tomcat服务器,然后再导入使用Jetty服务器所需的坐标:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>

配置文件

SpringBoot有两种配置文件格式,它们都在resources目录下:

  • properties格式:

    文件名为application.properties,格式如下:

    # 端口
    server.port=81
    # 访问路径
    server.servlet.context-path=/
    
  • yaml格式:

    文件名为application.ymlapplication.yaml,格式如下:

    server:
        # 端口
        port: 80
        servlet:
            # 访问路径
            context-path: /
    

    yaml格式的键值对中,键后面的冒号后(值的前面)一定要加空格。

SpringBoot程序的配置文件必须是application,只是后缀名不同。

以上三个配置文件可以同时存在,它们的优先级从高到低为:

  1. application.properties
  2. application.yml
  3. application.yaml

Idea可以快速地编辑配置文件:

yaml 语法

  • 大小写敏感。

  • 属性层级关系使用多行描述,每行结尾使用冒号结束。

  • 使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)。

    空格的个数并不重要,只要保证同层级的左侧对齐即可。

  • 属性值前面添加空格(属性名与属性值之间使用:+空格作为分隔)。

  • # 表示注释。

  • 数据前面要加空格与冒号隔开。

数组数据在数据书写位置的下方使用减号作为数据开始符号,每行书写一个数据,减号与数据间空格分隔。如:

list:
    - Java
    - Spring

读取配置数据

使用@Value("表达式")可以从配置文件中读取数据,注解中用于读取属性名引用方式是:${一级属性名.二级属性名……}。如:

@RestController
public class MyController {
    @Value("${server.port}")
    private Integer port;
    @Value("${list[0]}")
    private String java;

    @GetMapping("/config")
    public String gerConfig() {
        return "port=" + this.port + "\n" + this.java;
    }
}

SpringBoot还可以使用 @Autowired 注解注入 Environment 对象的方式读取数据。这种方式 SpringBoot 会将配置文件中所有的数据封装到 Environment 对象中,如果需要使用哪个数据只需要通过调用 Environment 对象的 getProperty(String name) 方法获取。如:

@RestController
public class MyController {
    
    @Autowired
    private Environment env;

    @GetMapping("/config")
    public String gerConfig() {
        return "port=" + env.getProperty("server.port");
    }

}

自定义对象

SpringBoot提供了将配置文件中的数据封装到我们自定义的实体类对象中的方式。具体操作如下:

  1. 在实体类上添加@Component注解。

    表示将实体类 bean 的创建交给 Spring 管理。

  2. 使用 @ConfigurationProperties 注解表示加载配置文件。

    在该注解中也可以使用 prefix 属性指定只加载指定键的数据。

  3. 在Controller中进行注入。

Example:

添加依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

在配置文件中添加:

myconfig:
  name: SpringBoot
  port: 80
  id: 666

实体类:

@Component
@ConfigurationProperties(prefix = "myconfig")
public class MyConfig {
    private String name;
    private Integer id;
    private Integer port;
    // getter and setter...
}

Controller:

@RestController
public class MyController {
    @Autowired
    private MyConfig myConfig;

    @GetMapping("/myconfig")
    public MyConfig getMyConfig() {
        return this.myConfig;
    }
}

多环境配置

由于开发环境、测试环境、生产环境的配置都不相同。所以SpringBoot给开发者提供了多环境的快捷配置,需要切换环境时只需要改一个配置即可。

  • yaml格式:

    # 开发
    spring:
      config:
        activate:
          # 配置环境名
          on-profile: dev
    # spring.profiles 配置已弃用
    server:
      port: 80
    ---
    # 生产
    spring:
      config:
        activate:
          on-profile: pro #给生产环境起的名字
    server:
      port: 81
    ---
    # 测试
    spring:
      config:
        activate:
          on-profile: test #给测试环境起的名字
    server:
      port: 82
    ---
    # 设置启用的环境
    spring:
      profiles:
        active: test  #表示使用的是开发环境的配置
    
  • properties格式:

    使用多文件方式,文件名以application-开头。如:

    • application-dev.properties

      server.port=80
      
    • application-pro.properties

      server.port=81
      
    • application-test.properties

      server.port=82
      

    SpringBoot只会默认加载名为 application.properties 的配置文件,所以需要在 application.properties 配置文件中设置启用哪个配置文件。如:

    spring.profiles.active=pro
    

SpringBoot提供了在运行jar时设置开启指定的环境的方式。如:

java –jar springbootdemo.jar –-spring.profiles.active=test

临时修改端口号:

java –jar springbootdemo.jar –-server.port=88

命令行设置的端口号优先级高于配置文件。 SpringBoot官网已经对配置的优先级进行了说明:

配置文件分类

SpringBoot定义了配置文件不同的放置的位置。而放在不同位置的优先级是不同的。SpringBoot中4级配置文件放置位置:

  1. classpath:application.yml
  2. classpath:config/application.yml
  3. file:application.yml
  4. file:config/application.yml

级别越高优先级越高。

第三方资源整合

整合 Junit

SpringBoot整合了Junit并可将其作为起步依赖整合到项目中:

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

SpringBoot整合Junit分为三步:

  1. 在测试类上添加 @SpringBootTest 注解。
  2. 使用 @Autowired 注入要测试的资源。
  3. 定义测试方法进行测试。

Example:

编写Service:

@Service
public class BookService {
    public void save() {
        System.out.println("Book save ...");
    }
}

测试BookService

@SpringBootTest
class SpringbootDemoApplicationTests {

    @Autowired
    private BookService bookService;

    @Test
    public void testSave() {
        bookService.save();
    }
}

由于引导类默认扫描当前包下的类和包,所以测试类(或者测试类的包)和引导类要在同个包下。

否则,可以使用@SpringBootTest注解的classes属性指定引导类的字节码对象。如:@SpringBootTest(classes = {SpringbootDemoApplication.class})

整合 MyBatis

在整合MyBatis前先建一个用于测试的数据库:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- Table structure for book_tb
DROP TABLE IF EXISTS `book_tb`;
CREATE TABLE `book_tb`  (
  `id` int NOT NULL,
  `name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb3 COLLATE = utf8mb3_bin ROW_FORMAT = Dynamic;

-- Records of book_tb
INSERT INTO `book_tb` VALUES (1, '郑嘉伦');
INSERT INTO `book_tb` VALUES (2, '钱璐');
INSERT INTO `book_tb` VALUES (3, '黄安琪');
INSERT INTO `book_tb` VALUES (4, '龙宇宁');
INSERT INTO `book_tb` VALUES (5, '姜宇宁');
INSERT INTO `book_tb` VALUES (6, '赵嘉伦');

SET FOREIGN_KEY_CHECKS = 1;
  • 导入依赖:

    1. 在创建项目时,通过Spring Initializr导入依赖:
    2. pom.xml中导入坐标:
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>3.0.0</version>
    </dependency>
    
    <dependency>
        <groupId>com.mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <scope>runtime</scope>
    </dependency>
    
  • 编写数据库配置:

    spring:
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/spring_db
        username: root
        password: 123456
    

    SpringBoot版本低于2.4.3(不含),Mysql驱动版本大于8.0时,需要在url连接串中配置时区 jdbc:mysql://localhost:3306/spring_db?serverTimezone=UTC,或在MySQL数据库端配置时区解决此问题。

  • 定义实体类:

    public class Book {
        private Integer id;
        private String name;
        // getter、setter and toString
    }
    
  • 定义DAO接口:

    @Mapper // SpringBoot定义DAO接口类
    public interface BookDao {
        @Select("SELECT * FROM book_tb WHERE id = #{id}")
        public Book getById(Integer id);
    }
    
  • 定义Test类:

    @SpringBootTest
    class SpringbootMybatisApplicationTests {
        @Autowired
        private BookDao bookDao;
    
        @Test
        public void testGetById() {
            Book book = bookDao.getById(1);
            System.out.println(book);
        }
    }
    

使用 Druid 数据源

SpringBoot有默认的数据源,但是也可以指定使用Druid数据源。

  • 导入Druid依赖:

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
    </dependency>
    
  • application.yml配置文件配置:

    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/spring_db?serverTimezone=UTC
        username: root
        password: 123456
        type: com.alibaba.druid.pool.DruidDataSource