SpringBoot

Spring Boot 是一个用于创建独立的、基于生产级别的 Spring 应用程序的框架。它简化了基于 Spring 的应用程序的开发过程,通过自动配置和约定优于配置的原则,减少了开发者在配置上的工作量。Spring Boot 还集成了大量常用的第三方库,使得开发者可以更快速地构建应用程序。同时,Spring Boot 也提供了一种内嵌式的容器,可以将应用程序打包成一个可执行的 JAR 文件,方便部署和运行。

SpringBoot是一个集成了Spring技术栈的一个大整合,是一个简化了Spring应用开发的框架,可以一站式解决J2EE的开发流程。

微服务架构

微服务架构(Microservice Architecture)是一种架构概念,旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦。你可以将其看作是在架构层次而非获取服务的

类上应用很多SOLID原则。微服务架构是个很有趣的概念,它的主要作用是将功能分解到离散的各个服务当中,从而降低系统的耦合性,并提供更加灵活的服务支持。

概念: 把一个大型的单个应用程序和服务拆分为数个甚至数十个的支持微服务,它可扩展单个组件而不是整个的应用程序堆栈,从而满足服务等级协议。

定义: 围绕业务领域组件来创建应用,这些应用可独立地进行开发、管理和迭代。在分散的组件中使用云架构和平台式部署、管理和服务功能,使产品交付变得更加简单。

本质: 用一些功能比较明确、业务比较精练的服务去解决更大、更实际的问题。

新建SpringBoot

IDEA创建项目

选择spring web依赖,springboot版本

hello world

package com.example.demo.demos.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "hello world";
    }
}

启动类


@SpringBootApplication
public class DemoApplication {

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

}
//spring 的一个组件

springboot依赖都是spring-boot-starter开始

打jar包 package

小配置

修改端口号

application.yml

server:
  port: 8080

修改banner

pom文件修改build

<resource>
    <directory>src/main/resources</directory>
    <includes>
        <include>**/*.properties</include>
        <include>**/*.xml</include>
        <include>**/*.yml</include>
        <include>**/banner.txt</include>
    </includes>
    <filtering>false</filtering>
</resource>

resources下新建banner.txt

banner.txt配置

  • ${AnsiColor.BRIGHT_YELLOW}:设置控制台中输出内容的颜色

  • ${application.version}:用来获取MANIFEST.MF文件中的版本号

  • ${application.formatted-version}:格式化后的${application.version}版本信息

  • ${spring-boot.version}:Spring Boot的版本号

  • ${spring-boot.formatted-version}:格式化后的${spring-boot.version}版本信息

效果

Spring Boot自动装配

Spring Boot 的自动装配是其核心特性之一,它通过约定优于配置的原则,大大简化了开发者的工作。Spring Boot 的自动装配是通过 @EnableAutoConfiguration 注解实现的,它会根据项目中的依赖和配置自动配置应用程序的上下文。以下是 Spring Boot 自动装配的一些重要特性:

  1. 条件化装配:Spring Boot 会根据项目中的条件自动装配相应的组件,例如根据类路径上的特定类或特定的 bean 是否存在来决定是否装配某个组件。

  2. 自动配置类:Spring Boot 会根据项目中的依赖和配置自动生成一系列的自动配置类,这些类会根据条件来决定是否生效,从而实现自动装配。

  3. 自动配置的优先级:Spring Boot 会根据条件的不同来确定自动配置的优先级,确保更具体的配置会覆盖更一般的配置。

  4. 自定义自动配置:开发者可以通过编写自定义的自动配置类来扩展 Spring Boot 的自动装配,从而满足特定的需求。

总之,Spring Boot 的自动装配大大简化了项目的配置工作,使开发者能够更专注于业务逻辑的开发,而不必过多关注底层的配置细节。这也是 Spring Boot 能够快速构建应用程序的重要原因之一。

pom.xml

spring-boot-dependencies:核心依赖在父工程

引入springboot依赖的时候,不需要指定版本,有版本仓库

启动器

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
</dependency>
  • 启动器:springboot的启动场景

  • 例如spring-boot-starter-web,就会导入web环境所有的依赖

  • springboot会将所有的功能场景,都变成一个一个的启动器

  • 需要什么功能,导入启动器即可

主程序

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

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

}

@SpringBootConfiguration注解流程图

注解含义

@SpringBootConfiguration : 标注在某个类上,表示这是一个Spring Boot的配置类;

@ComponentScan : 配置扫描路径,用于加载使用注解格式定义的bean

@EnableAutoConfiguration : 开启自动装配功能

@AutoConfigurationPackage 指定了默认的包规则 \color{#F0F}{指定了默认的包规则 }指定了默认的包规则就是将主程序类所在包及所有子包下的组件扫描到Spring容器中;

@Import(AutoConfigurationImportSelector.class) : 通过 @Import 注解导入 AutoConfigurationImportSelector类,然后通过该类的 s e l e c t I m p o r t s \color{#F0F}{selectImports }selectImports方法去读取MATE-INF/spring.factories文件中配置的组件的全类名,并按照一定的规则过滤掉不符合要求的组件的全类名,将剩余读取到的各个组件的全类名集合返回给IOC容器并将这些组件注册为bean

1.@AutoConfigurationPackage默认包规则详解

2.@Import(AutoConfigurationImportSelector.class)进行自动配置详解c

1、利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件

2、调用List configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类

3、利用工厂加载 Map<String, List> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件

4、从META-INF/spring.factories位置来加载一个文件。默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件**,按照条件装配( @ C o n d i t i o n a l ) 最终会按需配置 \color{#F0F}{按照条件装配(@Conditional)最终会按需配置}按照条件装配(@Conditional)最终会按需配置

Spring Boot 主启动类运行过程详解

  1. 引入依赖:在项目的 pom.xml 文件中引入 Spring Boot 相关的依赖,例如 spring-boot-starter-web

  2. 创建主启动类:创建一个类作为 Spring Boot 项目的主启动类,通常使用 @SpringBootApplication 注解标记该类。

  3. @SpringBootApplication 注解:这个注解是 Spring Boot 项目的入口注解,它包含了以下三个注解的功能:

    • @SpringBootConfiguration:标识该类是 Spring Boot 的配置类。

    • @EnableAutoConfiguration:开启自动配置功能,根据项目的依赖和配置自动配置应用程序的上下文。

    • @ComponentScan:配置组件扫描路径,用于加载使用注解格式定义的 bean。

  4. main 方法:在主启动类中编写 main 方法作为程序的入口点。在 main 方法中使用 SpringApplication.run() 方法启动 Spring Boot 应用程序。

  5. SpringApplication.run() 方法:这个方法会启动 Spring Boot 应用程序,并返回一个 ApplicationContext 对象,表示 Spring 应用程序的上下文。

  6. 自动装配:Spring Boot 会根据项目中的依赖和配置自动生成一系列的自动配置类,这些类会根据条件来决定是否生效,从而实现自动装配。

  7. 组件扫描:Spring Boot 会扫描主启动类所在包及其子包下的所有组件,将这些组件注册到 Spring 容器中。

  8. 启动内嵌容器:Spring Boot 提供了一种内嵌式的容器,可以将应用程序打包成一个可执行的 JAR 文件。在启动过程中,Spring Boot 会自动启动内嵌容器,如 Tomcat、Jetty 等,用于运行应用程序。

  9. 运行应用程序:一旦内嵌容器启动成功,Spring Boot 应用程序就会运行起来,可以通过浏览器或其他客户端访问应用程序提供的服务。

yaml语法

YAML(YAML Ain't Markup Language)是一种人类可读的数据序列化格式,常用于配置文件和数据交换。它使用缩进和特定的符号来表示数据结构,具有简洁、易读、易写的特点。下面是一些常用的 YAML 语法:

  1. 注释:使用 # 符号表示注释,注释后的内容会被忽略。

    # 这是一个注释
    key: value # 这也是一个注释
    
  2. 键值对:使用冒号 : 分隔键和值,键值对之间使用换行分隔。

    key: value
    
  3. 列表:使用 - 符号表示列表项,列表项之间使用换行分隔。

    - item1
    - item2
    
    [item1,item2]
    
  4. 嵌套结构:可以使用缩进表示嵌套的数据结构,缩进的空格数可以是 2 个或 4 个,但必须保持一致。

    key1:
      key2: value
    
  5. 多行字符串:使用 | 符号表示多行字符串,保留原始的换行和缩进。

    key: |
      This is a
      multi-line
      string.
    
  6. 引用:可以使用 & 符号定义引用,使用 * 符号引用已定义的引用。

    key1: &ref value
    key2: *ref
    
  7. 特殊字符:如果字符串中包含特殊字符(如冒号、空格等),可以使用引号将其括起来。

    key: "value with : and space"
    
  8. 环境变量:可以使用 ${} 表示环境变量。

    key: ${ENV_VAR}
    

这些是 YAML 的一些基本语法,可以根据需要进行灵活运用。在 Spring Boot 中,YAML 通常用于配置文件,可以方便地配置应用程序的属性和参数。

@ConfigurationProperties 将配置文件中的属性值注入到对象的属性中

在 Spring Boot 中,可以使用 @ConfigurationProperties 注解将配置文件中的属性值注入到对象的属性中。下面是一个示例代码:

首先,在 application.yml 配置文件中定义属性:

myapp:
  name: MyApp
  version: 1.0.0

然后,创建一个 MyAppProperties 类,用于接收配置文件中的属性值:

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {
    private String name;
    private String version;

    // 省略 getter 和 setter 方法

    @Override
    public String toString() {
        return "MyAppProperties{" +
                "name='" + name + '\'' +
                ", version='" + version + '\'' +
                '}';
    }
}

在上面的代码中,使用 @ConfigurationProperties 注解指定了属性的前缀为 myapp,这样 Spring Boot 就会将配置文件中以 myapp 开头的属性值注入到 MyAppProperties 对象的对应属性中。

最后,在需要使用配置属性的地方,可以直接注入 MyAppProperties 对象,并使用其中的属性值:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {
    @Autowired
    private MyAppProperties myAppProperties;

    @GetMapping("/info")
    public String getInfo() {
        return "Name: " + myAppProperties.getName() + ", Version: " + myAppProperties.getVersion();
    }
}

在上面的代码中,通过 @Autowired 注解将 MyAppProperties 对象注入到 MyController 类中,并在 getInfo() 方法中使用其中的属性值。

当应用程序启动时,Spring Boot 会自动将配置文件中的属性值注入到 MyAppProperties 对象中,并可以在 getInfo() 方法中获取到这些属性值。

@PropertySource 注入熟悉

在 Spring Boot 中,@PropertySource 注解用于指定外部属性文件的位置,并将属性文件中的属性值注入到 Spring 环境中。下面是关于 @PropertySource 注入属性的详细解释:

  1. 指定属性文件位置:通过 @PropertySource 注解可以指定外部属性文件的位置,例如 .properties.yml 文件。在 Spring Boot 中,通常在主启动类上使用 @PropertySource 注解指定属性文件的位置。

  2. 加载属性文件@PropertySource 注解会加载指定位置的属性文件,并将属性文件中的属性值加载到 Spring 的环境中,使得这些属性值可以在应用程序中被访问和使用。

  3. 属性值注入:一旦属性文件中的属性值被加载到 Spring 的环境中,可以通过 @Value 注解或 Environment 对象将这些属性值注入到应用程序中的 bean 或其他组件中。

  4. 示例代码:以下是一个示例代码,展示了如何使用 @PropertySource 注解加载外部属性文件并将属性值注入到 Spring Bean 中:

import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

@Component
@PropertySource("classpath:myapp.properties")
public class MyAppProperties {
    
    @Value("${myapp.name}")
    private String name;
    
    @Value("${myapp.version}")
    private String version;

    // 省略 getter 和 setter 方法

    @Override
    public String toString() {
        return "MyAppProperties{" +
                "name='" + name + '\'' +
                ", version='" + version + '\'' +
                '}';
    }
}

在上面的代码中,@PropertySource("classpath:myapp.properties") 指定了属性文件的位置为 classpath:myapp.properties,然后使用 @Value 注解将属性文件中的属性值注入到 MyAppProperties 类的属性中。

通过这种方式,可以方便地将外部属性文件中的属性值注入到 Spring Bean 中,实现配置的灵活性和可维护性。

JSR 303 校验

JSR 303 是 Java EE 6 中引入的一项规范,用于在 Java Bean 中定义校验规则,并在运行时执行校验。JSR 303 校验通过在 Java Bean 的字段上添加注解来定义校验规则,例如验证字段是否为空、长度是否符合要求、格式是否正确等。下面是 JSR 303 校验的一些重要概念和用法:

  1. 定义校验规则:通过在 Java Bean 的字段上添加 JSR 303 提供的注解,如 @NotNull@Size@Email 等,来定义校验规则。

  2. 校验执行:在需要执行校验的地方,如控制器方法中,通过调用校验器(Validator)的方法来执行校验。

  3. 校验结果:校验器会返回一个校验结果对象,其中包含了校验的详细信息,如校验是否通过、校验失败的字段、错误消息等。

  4. 校验注解:常用的 JSR 303 校验注解包括:

    注解

    作用类型

    解释

    @NotNull

    任何类型

    属性不能为null

    @NotEmpty

    集合

    集合不能为null,且size大于0

    @NotBlanck

    字符串、字符

    字符类不能为null,且去掉空格之后长度大于0

    @AssertTrue

    Boolean、boolean

    布尔属性必须是true

    @Min

    数字类型(原子和包装)

    限定数字的最小值(整型)

    @Max

    同@Min

    限定数字的最大值(整型)

    @DecimalMin

    同@Min

    限定数字的最小值(字符串,可以是小数)

    @DecimalMax

    同@Min

    限定数字的最大值(字符串,可以是小数)

    @Range

    数字类型(原子和包装)

    限定数字范围(长整型)

    @Length

    字符串

    限定字符串长度

    @Size

    集合

    限定集合大小

    @Past

    时间、日期

    必须是一个过去的时间或日期

    @Future

    时期、时间

    必须是一个未来的时间或日期

    @Email

    字符串

    必须是一个邮箱格式

    @Pattern

    字符串、字符

    正则匹配字符串

  5. 自定义校验规则:除了使用内置的校验注解外,还可以自定义校验注解和校验器,实现更复杂的校验逻辑。

  6. 校验分组:可以为校验注解指定校验分组,根据不同的分组执行不同的校验规则。

  7. 国际化支持:JSR 303 校验框架支持国际化,可以在校验注解中指定错误消息的国际化键,根据不同的语言环境返回对应的错误消息。

import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Data
public class PhoenixSaveDTO {
 
    @NotNull(message = "id不能为空")
    private Long id;
 
    @Future(message = "需要一个将来日期") // 只能是将来的日期
    @DateTimeFormat(pattern = "yyyy-MM-dd") // 日期格式化转换
    @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")//格式化接收的日期
    private LocalDate date;
 
    @DecimalMin(value = "0.1") // 最小值0.1元
    @DecimalMax(value = "10000.00") // 最大值10000元
    private BigDecimal doubleValue;
 
    @Min(value = 0, message = "最小值为0") // 最小值为1
    @Max(value = 127, message = "最大值为127") // 最大值88
    private Integer integer;
 
    @Range(min = 1, max = 100, message = "范围为1至100") // 限定范围
    private Long range;
 
    // 邮箱验证
    @Email(message = "邮箱格式错误")
    private String email;
 
    @Size(min = 10, max = 16, message = "字符串长度要求10到16之间。")
    private String size;
 
}
// 注意这里使用了@Valid 以及 BindingResult
public SysRes<Void> testBindingResult(@RequestBody @Valid PhoenixSaveDTO phoenixSaveDTO,
                                      BindingResult bindingResult){
    if( bindingResult.hasErrors() ){
        List<String> messageList = bindingResult.getFieldErrors().stream()
            .map(FieldError::getDefaultMessage)
            .collect(Collectors.toList());
        String message = String.valueOf(messageList);
        log.error("[参数校验异常:{}", message);
        return SysRes.fail(SysCode.PARAMS_EXCEPTION, message);
    }
    return null;
}

全局统一异常处理(入参校验)

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(BindException.class)
    public SysRes<Void> handlerBindException(BindException e, HttpServletRequest request) {
        String requestUri = request.getRequestURI();
        List<String> messageList = e.getBindingResult()
                .getFieldErrors()
                .stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.toList());
        String message = String.valueOf(messageList);
        log.error("[统一异常处理]请求地址:{}, 参数校验异常:{}", requestUri, message);
        return SysRes.fail(SysCode.PARAMS_EXCEPTION, message);
    }
}

Spring Boot 中的 Validation 概述

因Springboot的spring-boot-starter-web默认内置了Hibernate-Validator(Spring boot 2.3以前版本),虽然Hibernate-Validator也能做到数据校验,但是考虑到spring-boot-starter-validation 是一个抽象层,使得验证框架的具体实现变得可插拔。这意味着,除了 Hibernate Validator,开发者可以选择其他符合 Bean Validation 规范的实现。所以我们可以手动引入spring-boot-starter-validation实现数据验证。

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

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

spring-boot-starter-validation 不仅支持 JSR-303(Bean Validation 1.0)规范,还提供了对 JSR-380(Bean Validation 2.0)规范的全面支持。这使得开发者可以利用 Bean Validation 2.0 的新特性,更灵活地定义验证规则,包括对集合、嵌套对象的验证等。

通过在实体类的字段上使用标准的 Bean Validation 注解(如 @NotBlank@Size@Email 等),我们能够直观地定义数据的验证规则。这些验证规则会在应用程序的不同层次(如控制器层)生效,确保输入数据的正确性。

基本用法

Spring Boot Validation 提供了一系列注解,用于在实体类中定义验证规则。以下是一些常用的校验相关的注解及其功能以及用法:
1.@NotNull: 校验元素值不能为 null。如果元素为null,则验证失败。通常用于字段级别的验证。

@NotNull(message = "Name cannot be null")
private String name;

2.@NotBlank: 校验字符串元素值不能为 null 或空字符串。必须包含至少一个非空格字符(即执行trim()之后不为'')。如果元素为null或者‘‘,则验证失败。通常用于String类型的字段校验。

@NotBlank(message = "Username cannot be blank")
private String username;

3.NotEmpty: 校验集合元素或数组元素或者字符串是否非空。通常作用于集合字段或数组字段,此时需要集合或者数字的元素个数大于0。也可以作用于字符串,此时校验字符串不能为null或空串(可以是一个空格)。注意与@NotBlank的使用区别。

@NotEmpty(message = "List cannot be empty")
private List<String> items;

4.@Length: 校验字符串元素的长度。作用于字符串。注:Hibernate-Validator中注解,等同于spring-boot-starter-validation中的@Size

@Length(min = 5, max = 20, message = "Length must be between 5 and 20 characters")
private String username;

5.@Size: 校验集合元素个数或字符串的长度在指定范围内。在集合或字符串字段上添加 @Size 注解。

@Size(min = 1, max = 10, message = "Number of items must be between 1 and 10")
private List<String> items;

@Size(min = 5, max = 20, message = "Length must be between 5 and 20 characters")
private String username;

6.@Min: 校验数字元素的最小值。

@Min(value = 18, message = "Age must be at least 18")
private int age;

7.@Max: 校验数字元素的最大值。

@Max(value = 100, message = "Age must not exceed 100")
private int age;

9.@DecimalMax: 作用于BigDecimal类型字段, 校验字段的最大值,支持比较的值为字符串表示的十进制数。通常搭配它的inclusive()使用,区别边界问题。value 属性表示最大值,inclusive 属性表示是否包含最大值。

@DecimalMax(value = "100.00", inclusive = true, message = "Value must be less than or equal to 100.00")
private BigDecimal amount;

10.@DecimalMin: 作用于BigDecimal类型字段, 校验字段的最小值,支持比较的值为字符串表示的十进制数。通常搭配它的inclusive()使用,区别边界问题。value 属性表示最小值,inclusive 属性表示是否包含最小值。

@DecimalMin(value = "0.00", inclusive = false, message = "Value must be greater than 0.00")
private BigDecimal amount;

11.@Email: 校验字符串元素是否为有效的电子邮件地址。可以通过regexp自定义邮箱匹配正则。

@Email(message = "Invalid email address")
private String email;

12.@Pattern: 根据正则表达式校验字符串元素的格式。

@Pattern(regexp = "[a-zA-Z0-9]+", message = "Only alphanumeric characters are allowed")
private String username;

13.@Digits: 校验数字元素的整数部分和小数部分的位数。作用于BigDecimalBigInteger,字符串,以及byte, short,int, long以及它们的包装类型。

@Digits(integer = 5, fraction = 2, message = "Number must have up to 5 integer digits and 2 fraction digits")
private BigDecimal amount;

14.@Past: 校验日期或时间元素是否在当前时间之前。即是否是过去时间。作用于Date相关类型的字段。

@Past(message = "Date must be in the past")
private LocalDate startDate;

15.@Future: 校验日期或时间元素是否在当前时间之后。即是否是未来时间。作用于Date相关类型的字段。

@Future(message = "Date must be in the future")
private LocalDate endDate;

用法示例

1.定义接口入参请求参数
@Data  
public class UserCreateRequestVO {  
  
	@NotBlank(message = "请输入用户名")  
	@Size(max = 128, message = "用户名长度最大为128个字符")  
	private String userName;  
	  
	@Email(message = "请填写正确的邮箱地址")  
	private String email;  
	  
	@Min(value = 18, message = "用户年龄必须大于18岁")  
	@Max(value = 60, message = "用户年龄必须小于60岁")  
	private Integer age;  
	  
	@NotEmpty(message = "请输入你的兴趣爱好")  
	@Size(max = 5, message = "兴趣爱好最多可以输入5个")  
	private List<String> hobbies;  
	  
	@DecimalMin(value = "50", inclusive = false, message = "体重必须大于50KG")  
	private BigDecimal weight;  

	@Validated
	@NotNull(message = "请输入地址信息")  
	private UserAddressRequestVO address;  
}
2.定义请求接口
@RestController  
@RequestMapping("user")  
@Validated  
@Slf4j  
public class UserController {  
  
	/**  
	* 创建用户  
	* @param requestVO  
	* @return  
	*/  
	@PostMapping("create")  
	public ResultResponse<Void> createUser(@Validated @RequestBody UserCreateRequestVO requestVO){  
	return ResultResponse.success(null);  
	}  

	/**  
	* 校验用户邮箱是否合法  
	* @param email  
	* @return  
	*/  
	@GetMapping("email")  
	public ResultResponse<Void> validUserEmail(@Email(message = "邮箱格式不正确") String email){  
	return ResultResponse.success(null);  
	}
}

Spring Boot 环境配置文件位置及优先级

Spring Boot 支持多种类型的环境配置文件,包括 properties 文件和 YAML 文件。这些配置文件可以用于不同环境下的配置,如开发环境、测试环境和生产环境。Spring Boot 会根据一定的规则来加载这些配置文件,并根据优先级确定最终生效的配置。

配置文件位置

  1. 默认位置:Spring Boot 默认会在 src/main/resources 目录下查找 application.propertiesapplication.yml 文件作为默认的配置文件。

  2. 自定义位置:除了默认位置外,还可以在 src/main/resources 目录下创建自定义的配置文件,如 application-dev.propertiesapplication-test.yml 等,用于不同环境的配置。

  3. 外部位置:可以通过命令行参数或环境变量指定外部配置文件的位置,如 -Dspring.config.location=classpath:/custom-config.properties

配置文件优先级

Spring Boot 加载配置文件时会根据一定的优先级确定最终生效的配置,优先级由高到低依次为:

  1. 命令行参数:通过命令行参数指定的配置会覆盖其他位置的配置。

  2. 外部配置文件:通过环境变量或命令行参数指定的外部配置文件会覆盖默认位置的配置。

  3. 默认位置配置文件:默认位置的配置文件会作为基础配置,如果没有其他位置的配置会使用默认位置的配置。

  4. Profile 特定配置:在默认位置或自定义位置创建的 profile 特定配置文件(如 application-dev.propertiesapplication-test.yml)会覆盖默认位置的配置。

  5. 内嵌配置:内嵌配置(如 application.propertiesapplication.yml)会作为基础配置,如果没有其他位置的配置会使用内嵌配置。

通过以上优先级规则,Spring Boot 可以灵活地加载不同环境下的配置文件,并确保最终生效的配置符合预期。在实际开发中,可以根据不同的环境需求来管理和使用配置文件,从而实现灵活的配置管理。

Spring Boot 多环境配置

在实际开发中,一个应用程序通常需要在不同的环境中运行,例如开发环境、测试环境和生产环境。Spring Boot 提供了多种方式来实现多环境配置,以便在不同的环境中使用不同的配置参数。

1. 配置文件命名规则

Spring Boot 使用不同的配置文件命名规则来区分不同的环境,常见的命名规则包括:

  • application.properties:默认的配置文件,适用于所有环境。

  • application-{profile}.properties:针对特定环境的配置文件,{profile} 表示环境名称,例如 application-dev.propertiesapplication-test.propertiesapplication-prod.properties

  • application-{profile}.yml:YAML 格式的配置文件,同样适用于特定环境。

2. 配置文件内容

在不同的配置文件中,可以定义相同的属性名,但是根据不同的环境,属性值可以有所不同。例如,在 application-dev.properties 中可以定义开发环境的属性值,在 application-prod.properties 中可以定义生产环境的属性值。

3. 激活特定环境

可以通过以下方式来激活特定的环境:

  • application.properties 中使用 spring.profiles.active 属性指定激活的环境,例如 spring.profiles.active=dev

  • 在启动命令中使用 --spring.profiles.active 参数指定激活的环境,例如 java -jar myapp.jar --spring.profiles.active=dev

4. 使用 @Profile 注解

在代码中可以使用 @Profile 注解来标记特定环境下的配置类或 bean,例如:

@Configuration
@Profile("dev")
public class DevConfiguration {
    // 针对开发环境的配置
}

5. 多环境配置示例

假设有一个名为 application.properties 的默认配置文件,以及 application-dev.propertiesapplication-prod.properties 两个特定环境的配置文件,可以按照以下方式进行多环境配置:

# application.properties
spring.profiles.active=dev
# application-dev.properties
# 开发环境配置
server.port=8080
# application-prod.properties
# 生产环境配置
server.port=80

在上述示例中,通过 spring.profiles.active 属性指定了激活的环境为开发环境,而在不同的配置文件中定义了不同的 server.port 属性值,分别适用于开发环境和生产环境