SpringBoot 学习笔记

发布于 2024-12-22

Spring Initializr 生成的 SpringBoot 项目默认 pom.xml

<?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>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.18</version>
    <relativePath/> <!-- lookup parent from repository -->
  </parent>
  <groupId>com.example</groupId>
  <artifactId>demo</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <name>demo</name>
  <description>Demo project for Spring Boot</description>
  <url/>
  <licenses>
    <license/>
  </licenses>
  <developers>
    <developer/>
  </developers>
  <scm>
    <connection/>
    <developerConnection/>
    <tag/>
    <url/>
  </scm>
  <properties>
    <java.version>8</java.version>
  </properties>
  <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>

</project>

注意:当没有引入 spring-boot-starter-web 依赖时,启动应用后立即结束,并不会作为常驻进程。

SpringBoot 项目打包运行

  1. 引入打包插件

    <build>
      <plugins>
        <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
      </plugins>
    </build>
    
  2. 执行打包命令

    mvn package
    

打包成功后可以在 target 目录下找到生成的 JAR 包文件

  1. 运行 JAR 包
java -jar my-application.jar
# 覆盖配置文件中的参数
java -jar my-application.jar --spring.profiles.active=dev --server.port=8080

main 方法中的 String[] args 参数

public static void main(String[] args) {
    System.out.println(Arrays.toString(args));
    SpringApplication.run(MyApplication.class, args);
}

当执行 java -jar my-application --spring.profiles.active=dev --server.port=8080 时, 将看到 args 的输出内容为 [“–spring.profiles.active=dev”, “–server.port=8080”].

所以,也可以自己在 main 方法中构造好参数,传入 SpringApplication.run() 方法。例如

public static void main(String[] args) {
    String[] arg = new String[1];
    arg[0] = "--spring.profiles.active=prod";
    SpringApplication.run(MyApplication.class, arg);
}

SpringBoot 中配置文件的优先级

从上至下优先级越来越高。 同级别的路径中 properties 配置文件的优先级比 yml 配置文件的优先级高。

  1. classpath 中的 application.yml
  2. classpath 中的 config/application.yml
  3. 当前工作目录中的 application.yml
  4. 当前工作目录中的 config/application.yml

注意:当前工作目录是指执行 java 命令时所处的目录。

SpringBoot 多环境配置

在同一个 yml 配置文件中配置不同的环境

spring:
  profiles:
    active: dev

---
spring:
  profiles: dev

server:
  port: 8081

---
spring:
  profiles: test

server:
  port: 8082

---
spring:
  profiles: prod

server:
  port: 8083

可以看到配置文件中默认激活的是 dev 环境, 可以打包后执行 java -jar my-application.jar --spring.profiles.active=prod 指定激活的环境.

注意: spring.profiles=dev 被标记为已废弃的方式, 现在推荐使用 spring.config.activete.on-profile=dev 这种方式.

使用不同的文件配置多个环境

  1. application.yml 公共配置
  2. application-dev.yml 开发环境配置
  3. application-test.yml 测试环境配置
  4. application-prod.yml 生产环境配置

使用 spring.profiles.include 包含其他配置文件

比如,将数据库,缓存,消息队列等配置放置在不同的配置文件中,在主配置文件中使用 include 加载这些配置。

假设有如下配置文件:

application-db.yml
application-kafka.yml
application-redis.yml

主配置文件中可以这样配置:

spring:
  profiles:
    include: db,kafka,redis

启动应用后可以看到如下输出:

The following 3 profiles are active: "db", "kafka", "redis"

如果有相同的配置, 优先级顺序也是左边(db)优先级低, 右边(redis)优先级高。主配置文件中配置优先级是最低的。

注意: include 的配置文件是不包含文件名中 application- 前缀的。如果写错了,启动时也是不会报错的,可能不容易发现。

使用 spring.profiles.group 对配置文件分组

主配置文件中配置内容如下:

spring:
  profiles:
    active: prod
    group:
      dev: db,redis
      prod: db,kafka

启动时可以看到如下输出:

The following 3 profiles are active: "prod", "db", "kafka"

同样,如果有相同配置时,由左至右优先级越来越高。

springboot 配置文件中读取 pom.xml 文件中属性

pom.xml 文件中包含如下内容:

<profiles>
  <profile>
    <id>env_dev</id>
    <properties>
      <profile>dev</profile>
    </properties>
    <activation>
      <activeByDefault>true</activeByDefault>
    </activation>
  </profile>

  <profile>
    <id>env_prod</id>
    <properties>
      <profile>prod</profile>
    </properties>
  </profile>
</profiles>

application.yml 配置文件可以使用 @属性名@ 占位符读取 pom.xml 中对应的配置属性值:

spring:
  profiles:
    active: @profile@

启动时可以看到如下输出:

The following 1 profile is active: "dev"

这种配置方式带来的好处是开发阶段在 Idea 的 Maven 工具栏中可以直接通过勾选不同的环境来启动不同的环境。

在使用 Maven 打包时,可以通过 -P env_prod 来指定激活的 profile .

如果想要激活的 profile 不存在,可以在控制台看到如下警告:

[WARNING] The requested profile "prod" could not be activated because it does not exist.

此时,使用的将是 pom.xml 配置了 <activeByDefault> 默认激活的配置。 而如果没有配置任何默认激活的配置,也会打包成功,只是 application.yml 中的占位符 @profile@ 将不会被替换。 当执行 jar 时会报错:

ERROR org.springframework.boot.SpringApplication - Application run failed
org.yaml.snakeyaml.scanner.ScannerException: while scanning for the next token
found character '@' that cannot start any token. (Do not use @ for indentation)
 in 'reader', line 6, column 13:
        active: @profile@
                ^