说一个大家都知道的 Spring Boot 小细节!

简介: 说一个大家都知道的 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 打包的时候要不要带上这几个配置文件,但是咋一看,又感觉上面这段配置似乎有点矛盾,松哥来和大家捋一捋就不觉得矛盾了:

先来看第一个 resource,directory 就是项目的 resources 目录,includes 中就是我们三种格式的配置文件,另外还有一个 filtering 属性为 true,这是啥意思呢?这其实是说我们在 maven 的 pom.xml 文件中定义的一些变量,可以在 includes 所列出的配置文件中进行引用,也就是说 includes 中列出来的文件,可以参与到项目的编译中。

第二个 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,内容如下:

8af2f95a6e7443d5a7872ca7b41b8bc2.png

可以看到,引用的变量已经被替换了。

按照 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 中的变量了,像下面这样:

4ba271a4d840d3a30cc0ed54455cf183.png

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

53bef6f7374d4762409e53eae9d9c8f5.png在 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,则也可以手动勾选环境之后点击打包按钮,如下:

46c490ba0286494cc364aad64362f793.png

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

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

相关文章
|
8月前
|
存储 人工智能 Serverless
方案测评 | 零基础一键AI剧本生成与动画创作
阿里云推出基于AI技术的剧本生成与动画创作解决方案,利用函数计算FC、百炼模型服务和ComfyUI工具,实现从剧本撰写到视频合成的一站式自动化流程。该方案大幅降低动画制作的技术门槛与成本,加速内容生产,帮助创作者快速响应市场变化。通过体验发现,方案在高效性、创新性方面表现突出,但也存在视频生成时间较长、定制化功能不足等问题。整体而言,该方案为动画创作提供了新的可能性,尤其适合初创团队和个人创作者。
|
8月前
|
存储 缓存 API
电商行业中 API 接口的常见问题和解决方法
本文探讨了电商行业中API接口的常见问题及解决方法。涵盖数据准确性(如数据不一致、数据缺失)、性能问题(如响应时间过长、吞吐量不足)、安全问题(如身份认证与授权、数据泄露风险)和兼容性问题(如接口版本兼容性、系统兼容性)。通过优化数据同步机制、缓存策略、网络配置、服务器负载均衡、代码逻辑,以及采用安全的身份认证方式和加密技术,结合实际代码示例,帮助开发者提升API接口的稳定性和安全性,确保电商业务顺利运行。
379 11
|
8月前
|
安全 网络安全 开发工具
解决Ascend上vllm运行时出现urllib3.exceptions.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED]
在使用vllm模型时,运行示例代码下载模型文件时遇到了SSL安全校验问题。临时解决方案是修改`requests/sessions.py`文件中`request`函数的`verify`参数默认值为`False`。
|
7月前
|
传感器 算法 物联网
基于粒子群算法的网络最优节点部署优化matlab仿真
本项目基于粒子群优化(PSO)算法,实现WSN网络节点的最优部署,以最大化节点覆盖范围。使用MATLAB2022A进行开发与测试,展示了优化后的节点分布及其覆盖范围。核心代码通过定义目标函数和约束条件,利用PSO算法迭代搜索最佳节点位置,并绘制优化结果图。PSO算法灵感源于鸟群觅食行为,适用于连续和离散空间的优化问题,在通信网络、物联网等领域有广泛应用。该算法通过模拟粒子群体智慧,高效逼近最优解,提升网络性能。
286 16
|
9月前
|
人工智能 监控 前端开发
《C++ 与 JavaScript 携手:前端人工智能的创新融合之道》
在数字化时代,人工智能技术正迅速渗透至前端开发,C++与JavaScript的融合为前端智能化开辟新路径。C++的高效计算与JavaScript的灵活交互相结合,通过WebAssembly等技术,实现了复杂任务处理与用户界面的无缝对接,为智能图像识别、语音助手等应用提供了强大支持。面对开发复杂性和兼容性挑战,两者的深度融合仍需持续探索与优化。
145 26
|
10月前
|
设计模式 测试技术 Go
学习Go语言
【10月更文挑战第25天】学习Go语言
144 4
|
DataWorks 网络协议 Java
DataWorks操作报错合集之离线同步时,报错信息"Out of range value for column 'A' at row 1" ,表示什么意思
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
存储 NoSQL Redis
Redis 中bitMap使用及实现访问量
Redis 中bitMap使用及实现访问量
287 3
|
Linux 开发工具
在Linux中,如何创建一个新的分区并格式化为EXT4文件系统?
在Linux中,如何创建一个新的分区并格式化为EXT4文件系统?
|
网络安全 数据安全/隐私保护 Linux
2023年全国职业院校技能大赛=GZ073 网络系统管理赛项赛题第2套B模块-2
2023年全国职业院校技能大赛=GZ073 网络系统管理赛项赛题第2套B模块
2023年全国职业院校技能大赛=GZ073 网络系统管理赛项赛题第2套B模块-2