如何将Java常量作为Maven属性用于资源过滤?
能否将Java类中的常量作为Maven属性用于资源过滤?
我在Maven项目的src/main/java目录下有一个包含公开常量的Java类:
package my.package; public class MyClass { public static final String MY_PROPERTY = "my.property.name"; }
想知道能不能在src/main/resources的资源文件里,通过类似下面的方式引用这个常量值来做Maven资源过滤:
<myXmlFile> <property> <name>${java:my.package.MyClass#MY_PROPERTY}</name> <value>my value</value> </property> </myXmlFile>
Maven原生不支持直接通过${java:xxx}这类语法引用Java常量完成资源过滤,但可以通过以下几种方案实现需求:
方案1:用maven-antrun-plugin提取常量到Maven属性
借助Ant任务的脚本能力解析Java源码,提取常量值并设置为Maven属性,之后就能在资源过滤中直接引用。
配置示例:
<build> <plugins> <!-- 解析Java类提取常量 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>3.1.0</version> <executions> <execution> <phase>initialize</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <script language="javascript"> var file = new java.io.File("src/main/java/my/package/MyClass.java"); var scanner = new java.util.Scanner(file); var content = scanner.useDelimiter("\\Z").next(); scanner.close(); // 通过正则匹配常量值 var pattern = /public static final String MY_PROPERTY = "(.*?)";/; var matcher = pattern.matcher(content); if (matcher.find()) { project.setProperty("my.property.value", matcher.group(1)); } </script> </tasks> </configuration> </execution> </executions> </plugin> <!-- 开启资源过滤 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.3.1</version> <configuration> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </configuration> </plugin> </plugins> </build>
配置完成后,资源文件中可通过${my.property.value}引用该常量值。
方案2:用properties-maven-plugin反向生成(推荐)
更优雅的方式是先维护属性文件,再用插件自动生成包含常量的Java类,同时直接用属性文件做资源过滤,避免重复维护。
步骤示例:
- 在
src/main/resources下创建constants.properties:
MY_PROPERTY=my.property.name
- 配置插件生成Java类并开启资源过滤:
<build> <plugins> <!-- 从properties文件生成Java常量类 --> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>properties-maven-plugin</artifactId> <version>1.1.0</version> <executions> <execution> <phase>generate-sources</phase> <goals> <goal>generate-properties</goal> </goals> <configuration> <outputFile>target/generated-sources/java/my/package/MyClass.java</outputFile> <propertiesFile>src/main/resources/constants.properties</propertiesFile> <packageName>my.package</packageName> <className>MyClass</className> <access>public</access> </configuration> </execution> </executions> </plugin> <!-- 用properties文件做资源过滤 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.3.1</version> <configuration> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>**/*.xml</include> </includes> </resource> </resources> <filters> <filter>src/main/resources/constants.properties</filter> </filters> </configuration> </plugin> </plugins> <!-- 将生成的Java类加入编译路径 --> <resources> <resource> <directory>target/generated-sources/java</directory> </resource> </resources> </build>
此时资源文件可直接用${MY_PROPERTY}引用,Java常量类也会自动生成,兼顾代码和配置的一致性。
方案3:自定义Maven插件
如果以上方案无法满足定制化需求,可以开发简单的自定义插件,在编译阶段解析Java类中的常量并注入到Maven属性中。不过这种方式开发成本较高,仅适合特殊场景。
内容的提问来源于stack exchange,提问作者Nth Dimension
相关产品推荐
相关产品推荐

