SpringBoot构建时替换依赖Jar中ServerInfo.properties属性值方案咨询
我完全懂你的需求——要在构建Spring Boot应用时,修改最终生成的Jar包里tomcat-embed-core-8.5.23.jar中的org.apache.catalina.util.ServerInfo.properties属性值,同时绝对不能改动本地仓库里的原依赖Jar。Maven过滤器确实只能处理项目自身资源目录下的文件,没法直接操作依赖Jar里的内容,下面给你两种实用的解决方案:
方案一:用Maven插件组合实现“提取-修改-替换”
这个思路是先把依赖里的目标文件提取到本地临时目录,修改内容后,再让它在最终打包时覆盖原依赖里的文件:
提取依赖中的ServerInfo.properties到临时目录
在pom.xml中添加maven-dependency-plugin配置,专门提取目标文件:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>extract-tomcat-server-info</id> <phase>process-resources</phase> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>8.5.23</version> <outputDirectory>${project.build.directory}/tomcat-temp</outputDirectory> <includes>org/apache/catalina/util/ServerInfo.properties</includes> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin>修改提取出来的属性文件
用properties-maven-plugin自动化修改指定属性,避免手动操作的繁琐:<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>properties-maven-plugin</artifactId> <executions> <execution> <id>modify-server-info</id> <phase>process-resources</phase> <goals> <goal>write-project-properties</goal> </goals> <configuration> <file>${project.build.directory}/tomcat-temp/org/apache/catalina/util/ServerInfo.properties</file> <entries> <!-- 替换成你需要的属性值,比如自定义服务器标识 --> <entry> <key>server.info</key> <value>My Custom Tomcat/8.5.23</value> </entry> <entry> <key>server.number</key> <value>8.5.23-custom-build</value> </entry> </entries> </configuration> </execution> </executions> </plugin>让修改后的文件优先被打包
Spring Boot打包时会优先使用项目classes目录下的文件,所以我们把修改好的文件复制到对应路径:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <executions> <execution> <id>copy-modified-server-info</id> <phase>process-resources</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${project.build.outputDirectory}</outputDirectory> <resources> <resource> <directory>${project.build.directory}/tomcat-temp</directory> <includes> <include>org/apache/catalina/util/ServerInfo.properties</include> </includes> </resource> </resources> </configuration> </execution> </executions> </plugin>这样最终生成的Spring Boot Jar里,自定义的
ServerInfo.properties会完全覆盖依赖Jar中的原文件,而本地仓库里的tomcat-embed-coreJar丝毫不受影响。
方案二:用Spring Boot动态配置覆盖(更优雅)
如果你的需求只是修改Tomcat对外展示的服务器标识(比如响应头里的Server字段),其实没必要直接修改属性文件,用Spring Boot的自定义配置就能动态覆盖:
创建一个配置类,实现TomcatServletWebServerFactoryCustomizer:
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.server.WebServerFactoryCustomizer; import org.springframework.stereotype.Component; @Component public class CustomTomcatServerInfoCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> { @Override public void customize(TomcatServletWebServerFactory factory) { factory.addContextCustomizers(context -> { // 直接覆盖ServerInfo的展示内容 context.getServletContext().setAttribute("org.apache.catalina.util.ServerInfo", "My Custom Tomcat/8.5.23-custom"); // 如果需要更细粒度修改(比如修改所有属性),可以用反射操作ServerInfo实例 // 注意:反射修改私有字段需要谨慎使用 }); } }
这种方式不需要碰任何Jar包内容,在应用启动时动态修改Tomcat的配置,完全符合Spring Boot的设计理念,也不会对依赖Jar产生任何改动。
简单总结:如果要修改ServerInfo.properties里的所有属性,方案一更直接;如果只是修改对外展示的标识,方案二更优雅。
内容的提问来源于stack exchange,提问作者AR3Y35

