有没有一种方法可以在Java类编译时使用Maven属性?

44
我想在编译时在Java类中使用maven占位符以减少重复。类似这样:

pom.xml
<properties>
  <some.version>1.0</some.version>
</properties>

SomeVersion.java

package some.company;

public class SomeVersion {

    public static String getVersion() {
        return "${some.version}"
    }

}
4个回答

66

只需在src/main/resources中创建名为app.properties的文件,其内容如下

application.version=${project.version}

然后像这样启用Maven过滤

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>

就这些 - 在应用程序代码中读取属性文件即可

ClassPathResource resource = new ClassPathResource( "app.properties" );
p = new Properties();
InputStream inputStream = null;
try {
    inputStream = resource.getInputStream();
    p.load( inputStream );
} catch ( IOException e ) {
    LOGGER.error( e.getMessage(), e );
} finally {
    Closeables.closeQuietly( inputStream );
}

并提供像这样的方法

public static String projectVersion() {
    return p.getProperty( "application.version" );
}

1
+1 - 这绝对比通过预处理器输入源代码要好。 - Stephen C
5
ClassPathResource不是Spring特有的吗?OP没有包含spring标签。 - fegemo
在我看来,这种方法比这里描述的properties-maven-plugin更好(它也可以工作)。 - aspadacio
2
只是提醒一下,ClassPathResource 只适用于 Spring。如果你想在普通的 Java 中实现这个逻辑,它是行不通的。 - Nitish Kumar
@NitishKumar,也许你会遇到这个问题,因为你跳过了pom文件部分(将文件设置为过滤器)。@fegemo,你可以使用简单的Java代码getClass.getClassLoader.getResourceAsStream("app.properties")来完成。 - Ohad Bitton
显示剩余3条评论

10

虽然这不是一个非常好的解决方案,但在默认的Maven资源插件中是可以实现的。

首先,您需要指定资源插件。

<project>
  <build>
    <!-- Configure the source files as resources to be filtered
      into a custom target directory -->
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <filtering>true</filtering>
        <targetPath>../filtered-sources/java</targetPath>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
  </build>
</project>

接下来,您需要更改编译器插件的“默认”配置。

<project>
  <build>
      <!-- Overrule the default pom source directory to match
            our generated sources so the compiler will pick them up -->
      <sourceDirectory>target/filtered-sources/java</sourceDirectory>
  </build>
</project> 

我同意这不是最好的或者也许不是最合适的方法,但这是一种方法。 - Jeroen
@Jeroen 是的,我同意你的观点。虽然我无法以这种方式复现,但它扩展了我的知识面。感谢你的回答。 - Dmytro Chyzhykov
2
为此,使用templating-maven-plugin。它执行了maven-resources-plugin中包含的一些操作,但不需要编写数十行XML代码。请参见http://mojo.codehaus.org/templating-maven-plugin/和我在另一个SO问题上的答案:https://dev59.com/E2855IYBdhLWcg3w3IVh#18452939 - Baptiste Mathus

5
我知道的最简单的方法是使用Templating Maven Plugin
将插件声明添加到您的pom中:
<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>templating-maven-plugin</artifactId>
    <version>1.0.0</version>
    <executions>
        <execution>
            <id>filter-src</id>
            <goals>
                <goal>filter-sources</goal><!-- add this if you filter main sources -->
                <goal>filter-test-sources</goal><!-- add this if you filter test sources -->
            </goals>
        </execution>
    </executions>
</plugin>

如果您正在过滤主要源代码:
  • 创建文件夹src/main/java-templates
  • 将您想要过滤的源文件移动到该文件夹中。复制包树结构,就好像您在src/main中一样。
如果您还要过滤测试源代码:
  • 创建文件夹src/test/java-templates
  • 将您想要过滤的源文件移动到该文件夹中。复制包树结构,就好像您在src/test中一样。
假设您的源代码包含有效的占位符:
package some.company;

public class SomeVersion {

    public static String getVersion() {
        return "${project.version}"
    }

}

现在当您编译或测试项目时,这些占位符应该已经有了值。
希望能对您有所帮助。

3

如果您正在使用Spring,您可以注入属性。步骤如下:

  1. 在POM文件中定义所需的所有配置文件,并且每个配置文件必须拥有自定义属性,在您的情况下。

<profile>
 <id>dev</id>
 <properties>
  <some.version>Dev Value</some.version>
 </properties>
</profile>

  1. 在您的个人资料的“构建”部分中,您定义了过滤器注入。
  2. 在您的项目资源目录下,创建一个属性文件(任何助记符基督教名字),并将您要注入的属性放入其中:

custom.some.version=${some.version}

  1. 在spring-context文件中定义属性占位符,并定义您的bean或beanProperty:

<context:property-placeholder location="classpath*:/META-INF/*.properties"/>
...
<bean id="customConfig" class="com.brand.CustomConfig">
 <property name="someVersion" value="${custom.some.version}" />
</bean>
...

创建你的类。
package com.brand;

public class CustomConfig {
  private String someVersion;

  public getSomeVersion() {
  return this.someVersion;
  }

  public setSomeVersion(String someVersion) {
  this.someVersion = someVersion;
  }
}
  1. 在你想要使用的地方注入。这个例子中使用了自动装配的bean,但你也可以使用自动装配的属性。
package com.brand.sub

public class YourLogicClass {
  @Autowired
  private CustomConfig customConfig;

  // ... your code
}
在最终编译中,您将得到正确的值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接