惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
I
InfoQ
U
Unit 42
WordPress大学
WordPress大学
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Apple Machine Learning Research
Apple Machine Learning Research
J
Java Code Geeks
月光博客
月光博客
D
Docker
Stack Overflow Blog
Stack Overflow Blog
D
DataBreaches.Net
阮一峰的网络日志
阮一峰的网络日志
Blog — PlanetScale
Blog — PlanetScale
V
Visual Studio Blog
博客园 - 聂微东
A
About on SuperTechFans
腾讯CDC
Jina AI
Jina AI
Microsoft Azure Blog
Microsoft Azure Blog
GbyAI
GbyAI
博客园 - 【当耐特】
罗磊的独立博客
博客园 - 三生石上(FineUI控件)
M
MIT News - Artificial intelligence

博客园 - 华安

C#中Microsoft.Extensions.Caching.Memory 与 System.Runtime.Caching.MemoryCache区别 自适应网格系统:CSS Grid中repeat()、auto-fill与auto-fit的深度解析 CSS3中响应式布局两大神器display:flex和display:grid CSS中元素的display显示方式有多种,隐藏、块级、内联、内联-块级 SQl Server 中的 go 是什么作用 CSS中 display:flex的align-items: stretch; 移动端浏览器(尤其是 iOS Safari)的橡皮筋回弹效果(Overscroll / Bounce Effect) 手机端浏览器上ES6中的Fetch回调执行 window.open没效果 用Flex实现兼容性好的全屏布局 在 VS Code 中使用 C# Dev Kit 和 Unity Tools 调试 Unity 2022 Unity 可编程物件(ScriptableObject) 微信小程序中的 联系客服 最基本的使用方法 wx.requestSubscribeMessage(Object object) 和 wx.requestSubscribeDeviceMessage(Object object) 这两个有什么区别 微信小程序中 wx.hideLoading() 后调用 wx.showToast()的问题 Windows 中启动 Nginx的常用命令 CSS进阶技巧:字体渐变、描边、倒影与渐变色描边全解析 netCore 中各DLL引用了 SkiaSharp.dll的问题 unity中预制体解包 在 Unity 中,Time.timeScale实现游戏暂停加速等 微信小程序中关联微信支付 unity中的 Navigation AI使用 C#中TaskCompletionSource(简称 TCS)学习 Unity 编辑器 中,快捷键 Ctrl + Shift + F 的功能 unity中按下 F键,让物体聚焦 微信中进入定页面的,判断时通过扫二维码进入的,还是点小程序名称进入的 MYSQL中从JSON字符串中提取指定的值 Unity2022中创建动画 Animation(旧方法) Unity 中区别,public 和 [SerializeField] Unity中 onCollisionEnter2D与OnTriggerEnter2D 区别 asp.netCore中给动态请求路径加客户端缓存
springBoot中的 pom.xml文件 bulid学习
华安 · 2026-09-15 · via 博客园 - 华安

最近在学习springBoot中,看到了 pom.xml中的bulid代码:

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

这段 Maven pom.xml 配置片段主要包含两个核心部分:‌Spring Boot 打包插件‌和‌资源过滤配置‌。以下是对其作用的详细解析及潜在风险提示。

1. spring-boot-maven-plugin插件

该插件是 Spring Boot 官方提供的核心构建插件,其主要作用是将普通的 Maven JAR 包转换为‌可独立运行的“Fat Jar”(或称 Uber Jar)‌。

  • ‌打包可执行 Jar‌:它会将项目的所有依赖库(dependencies)重新打包并嵌入到最终的 JAR 文件中,同时生成特定的目录结构(如 BOOT-INF/libBOOT-INF/classes)和启动类信息(Start-Class)。这使得生成的 JAR 包可以通过 java -jar app.jar 命令直接运行,无需额外配置 Classpath。
  • ‌开发支持‌:在开发阶段,该插件还支持热部署(DevTools)和应用的快速重启,提升开发效率。
  • ‌构建信息生成‌:它可以生成 build-info.properties 文件,包含构建时间、版本等信息,便于应用监控和排查问题。

‌注意‌:如果未指定 <version>,Maven 通常会继承 spring-boot-starter-parent 中定义的版本。若未使用 parent POM,则必须显式指定版本,否则可能导致构建失败或行为不可控。

2. <resources> 与 <filtering>true</filtering>

这部分配置启用了 Maven 的‌资源过滤(Resource Filtering)‌功能。

  • ‌占位符替换‌:当 <filtering> 设置为 true 时,Maven 在将 src/main/resources 目录下的文件复制到输出目录(如 target/classes)之前,会扫描文件内容。它会识别其中的 ${...} 占位符(例如 ${project.version}${db.url}),并将其替换为 pom.xml 中定义的属性值、系统属性或 profile 中激活的属性值。
  • ‌多环境适配‌:这是实现多环境配置(开发、测试、生产)的关键机制。结合 <profiles>,可以为不同环境定义不同的属性值,从而在构建时自动生成对应环境的配置文件。
  • 资源过滤开启后,资源文件中包含 ${...} 的地方会被替换成 POM 文件中的属性或系统属性。因此如果你有配置文件比如 application.properties,文件内的变量可以被替换。
  • 但要注意,部分二进制文件(如图片、jar 包等)不应该开启过滤,否则会导致文件损坏。
  • 通常只对文本资源开启过滤,或将需要过滤的资源独立目录单独设置资源过滤

⚠️ 重要风险与最佳实践

虽然上述配置很常见,但‌全局开启资源过滤(<filtering>true</filtering>)存在严重风险‌,特别是当资源目录中包含二进制文件时。

风险:二进制文件损坏

Maven 的资源过滤机制是基于文本处理的。如果 src/main/resources 目录下包含‌二进制文件‌(如 .keystore.jks.p12.png.jpg.gif.woff 等),开启过滤后,Maven 会尝试以文本方式读取并替换这些文件中的内容。这会导致二进制数据被破坏,从而使证书失效、图片无法显示或字体加载错误。

推荐的最佳实践配置

为了安全地使用资源过滤,建议采用‌排除二进制文件‌或‌分离配置‌的策略。以下是更 robust 的配置示例:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
    
    <resources>
        <!-- 配置1:处理需要过滤的文本文件 -->
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <!-- 排除所有已知的二进制文件后缀 -->
            <excludes>
                <exclude>**/*.keystore</exclude>
                <exclude>**/*.jks</exclude>
                <exclude>**/*.p12</exclude>
                <exclude>**/*.pfx</exclude>
                <exclude>**/*.cer</exclude>
                <exclude>**/*.png</exclude>
                <exclude>**/*.jpg</exclude>
                <exclude>**/*.jpeg</exclude>
                <exclude>**/*.gif</exclude>
                <exclude>**/*.ico</exclude>
                <exclude>**/*.woff</exclude>
                <exclude>**/*.woff2</exclude>
                <exclude>**/*.ttf</exclude>
                <exclude>**/*.eot</exclude>
                <exclude>**/*.svg</exclude> <!-- svg虽是文本,但通常不建议过滤以防万一 -->
            </excludes>
        </resource>
        
        <!-- 配置2:处理不需要过滤的二进制文件 -->
        <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
            <includes>
                <include>**/*.keystore</include>
                <include>**/*.jks</include>
                <include>**/*.p12</include>
                <include>**/*.png</include>
                <include>**/*.jpg</include>
                <!-- 包含其他所有二进制格式 -->
            </includes>
        </resource>
    </resources>
</build>

或者,使用 maven-resources-plugin<nonFilteredFileExtensions> 配置(需确保插件版本较新,如 3.3.1+):

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <configuration>
        <encoding>UTF-8</encoding>
        <nonFilteredFileExtensions>
            <nonFilteredFileExtension>keystore</nonFilteredFileExtension>
            <nonFilteredFileExtension>jks</nonFilteredFileExtension>
            <nonFilteredFileExtension>p12</nonFilteredFileExtension>
            <nonFilteredFileExtension>png</nonFilteredFileExtension>
            <nonFilteredFileExtension>jpg</nonFilteredFileExtension>
            <nonFilteredFileExtension>gif</nonFilteredFileExtension>
        </nonFilteredFileExtensions>
    </configuration>
</plugin>

总结

你提供的配置实现了 Spring Boot 的可执行打包和动态资源替换功能,但在实际项目中,‌务必注意避免对二进制资源文件进行过滤‌,否则会导致应用运行时出现难以排查的错误。建议采用排除法或专门的非过滤配置来保护二进制文件。

 注意一个templates目录下的 

  • Thymeleaf 模板(.html
  • FreeMarker 模板(.ftl
  • Velocity 模板(.vm

1、这些模板文件会在运行时由对应的模板引擎加载并渲染。

2、是否开启过滤的考虑点

开启过滤:

  • 资源过滤会在构建时将文件中的 ${...} 或其他占位符替换成 Maven 属性或自定义属性的值。
  • 如果你希望在构建时就动态替换模板中的某些变量(如版本号、构建时间、服务器地址等),可以开启过滤。
  • 但要特别注意,模板引擎本身常用 ${...} 来表示变量,如果 Maven 过滤抢先把它替换了,模板的动态功能就会失效。

关闭过滤:

  • 如果模板中的 ${...} 是模板引擎要在运行时解析的变量,最好不要开启过滤。
  • 避免构建时把模板里的变量“提前替换”,破坏了模板的动态渲染功能。
  • 一般建议把模板文件保持原样,交给模板引擎处理。

3. 典型建议

  • 不要对存放模板的 templates 目录开启 <filtering>true</filtering>
  • 如果确实需要过滤某些配置文件或资源,可以专门建立一个带过滤的资源目录(比如 src/main/filtered-resources),单独管理。
  • 如果想在模板里引用类似构建时间、版本号这种固定数据,可以通过模板引擎传递参数或使用占位符文件替换机制,而不是 Maven 过滤。

4. 具体示例

<resources>
    <resource>
        <directory>src/main/resources</directory>
        <filtering>false</filtering> <!-- 关闭过滤 -->
    </resource>
</resources>

模板目录(如 templates)一般在 src/main/resources/templates 下,默认继承了上述配置。

总结

是否应该过滤模板资源理由
保持模板中 ${} 由模板引擎渲染,不被 Maven 替换
是(少见) 构建时需要替换特定 Maven 属性,且模板不影响动态变量解析