乐趣区

关于java:说一个大家都知道的-Spring-Boot-小细节

小伙伴们晓得,咱们在创立 Spring Boot 我的项目的时候,默认都会有一个 parent,这个 parent 中帮咱们定了我的项目的 JDK 版本、编码格局、依赖版本、插件版本等各种常见内容,有的小伙伴可能看过 parent 的源码,这个源码里边有这么一个配置:

<resources>
  <resource>
    <directory>${basedir}/src/main/resources</directory>
    <filtering>true</filtering>
    <includes>
      <include>**/application*.yml</include>
      <include>**/application*.yaml</include>
      <include>**/application*.properties</include>
    </includes>
  </resource>
  <resource>
    <directory>${basedir}/src/main/resources</directory>
    <excludes>
      <exclude>**/application*.yml</exclude>
      <exclude>**/application*.yaml</exclude>
      <exclude>**/application*.properties</exclude>
    </excludes>
  </resource>
</resources>

首先小伙伴们晓得,这个配置文件的目标次要是为了形容在 maven 打包的时候要不要带上这几个配置文件,然而咋一看,又感觉下面这段配置仿佛有点矛盾,松哥来和大家捋一捋就不感觉矛盾了:

  1. 先来看第一个 resource,directory 就是我的项目的 resources 目录,includes 中就是咱们三种格局的配置文件,另外还有一个 filtering 属性为 true,这是啥意思呢?这其实是说咱们在 maven 的 pom.xml 文件中定义的一些变量,能够在 includes 所列出的配置文件中进行援用,也就是说 includes 中列出来的文件,能够参加到我的项目的编译中。
  2. 第二个 resource,没有 filter,并且将这三个文件排除了,意思是我的项目在打包的过程中,除了这三类文件之外,其余文件间接拷贝到我的项目中,不会参加我的项目编译。

总结一下就是 resources 下的所有文件都会被打包到我的项目中,然而列出来的那三类,不仅会被打包进来,还会参加编译。

这下就清晰了,下面这段配置实际上并不矛盾。

那么在 properties 或者 yaml 中,该如何援用 maven 中的变量呢?

这块本来的写法是应用 $ 符号来援用,然而,咱们在 properties 配置文件中,往往用 $ 符号来援用以后配置文件的另外一个 key,所以,咱们在 Spring Boot 的 parent 中,还会看到上面这行配置:

<properties>
  <java.version>17</java.version>
  <resource.delimiter>@</resource.delimiter>
  <maven.compiler.source>${java.version}</maven.compiler.source>
  <maven.compiler.target>${java.version}</maven.compiler.target>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>

这里的 <resource.delimiter>@</resource.delimiter> 就示意将资源援用的符号改为 @ 符号。也就是在 yaml 或者 properties 文件中,如果咱们想援用 pom.xml 中定义的变量,就能够通过 @ 符号来援用。

松哥举一个简略的例子,假如我想在我的项目的 yaml 文件中配置以后我的项目的 Java 版本,那么我就能够像上面这样写:

app:
  java:
    version: @java.version@

这里的 @java.version@ 就示意援用了 pom.xml 中定义的 java.version 变量。

当初咱们对我的项目进行编译,编译之后再关上 application.yaml,内容如下:

能够看到,援用的变量曾经被替换了。

依照 Spring Boot parent 中默认的配置,application.yaml、application.yml 以及 application*.properties 文件中能够援用 pom.xml 中定义的变量,其余文件则不能够。如果其余文件也想援用,就要额定配置一下。

例如,想让 txt 文件援用 pom.xml 中的变量,咱们能够在 pom.xml 中做如下配置:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.txt</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

include 所有的 txt 文件,并且设置 filtering 为 true(不设置默认为 false),而后咱们就能够在 resources 目录下的 txt 文件中援用 pom.xml 中的变量了,像上面这样:

编译之后,这个变量援用就会被替换成真正的值:

在 yaml 中援用 pom.xml 的配置,有一个十分经典的用法,就是多环境切换。

假如咱们当初我的项目中有开发环境、测试环境以及生产环境,对应的配置文件别离是:

  • application-dev.yaml
  • application-test.yaml
  • application-prod.yaml

咱们能够在 application.yaml 中指定具体应用哪个配置文件,像上面这样:

spring:
  profiles:
    active: dev

这个示意应用开发环境的配置文件。

然而有时候咱们的环境信息是配置在 pom.xml 中的,例如 pom.xml 中蕴含如下内容:

<profiles>
    <profile>
        <id>dev</id>
        <properties>
            <package.environment>dev</package.environment>
        </properties>
        <!-- 是否默认 true 示意默认 -->
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>prod</id>
        <properties>
            <package.environment>prod</package.environment>
        </properties>
    </profile>
    <profile>
        <id>test</id>
        <properties>
            <package.environment>test</package.environment>
        </properties>
    </profile>
</profiles>

这里配置了三个环境,其中默认是 dev(activeByDefault)。那么咱们在 application.yaml 中就能够应用 package.environment 来援用以后环境的名称,而不必硬编码。如下:

spring:
  profiles:
    active: @package.environment@

此时,咱们通过 maven 命令对我的项目打包时,就能够指定以后环境的版本了,例如应用 test 环境,打包命令如下:

mvn package -Ptest

打包之后咱们去看 application.yaml,就会发现里边的环境曾经是 test 了。

如果你应用的是 IDEA,则也能够手动勾选环境之后点击打包按钮,如下:

能够先勾选下面的环境信息,再点击上面的打包。

好啦,一个小小知识点,因为有小伙伴在微信上问这个问题,就拿进去和大家分享下。

退出移动版