无法在带有@Value的Spring应用程序中获取maven project.version属性

时间:2016-08-16 20:30:28

标签: maven spring-boot

如何在带有@Value注释的Spring Boot应用程序中获取maven project.version属性?

5 个答案:

答案 0 :(得分:61)

经过一些关于如何在Spring Boot应用程序中获取maven项目版本的研究和试验,我无法找到适合我的任何内容。

由于类加载器问题,使用清单肯定是一条腐烂的路径,即一个获得Spring发现的第一个清单,在我的情况下不是我的应用程序。

我发现的一个解决方案是使用maven资源插件来过滤" (替换)资源文件中的属性。在这种情况下,Spring application.properties

以下是使这项工作的步骤。

在pom中,使用以下定义激活资源过滤:

    <resources>
        <resource>
            <filtering>true</filtering>
            <directory>src/main/resources</directory>
            <includes>
                <include>application.properties</include>
            </includes>
        </resource>
    </resources>

application.properties文件中:

  application.name=@project.artifactId@
  build.version=@project.version@
  build.timestamp=@timestamp@

请注意application.properties文件中的@ property @而不是$ {property}。

spring-boot-starter-parent pom将标准的$ {}分隔符重新定义为@:

    <resource.delimiter>@</resource.delimiter> <!-- delimiter that doesn't clash with Spring ${} placeholders -->
    <delimiters>
        <delimiter>${resource.delimiter}</delimiter>
    </delimiters>

然后可以使用@Value在Spring中访问这些属性,如下所示:

@Value("${application.name}")
private String applicationName;

@Value("${build.version}")
private String buildVersion;

@Value("${build.timestamp}")
private String buildTimestamp;

A sample project is available here

答案 1 :(得分:14)

要访问 Spring Boot应用程序中的Maven属性,我们需要的是在@中用定界符application.properties映射它们,如下所示:

app.version=@project.version@
app.name=@project.name@

然后像普通属性一样在应用程序中使用它们,例如:

@Service
public class SomeService {

   @Value("${app.version}")
   private String appVersion;

   // other stuff
}

来源:Automatic Property Expansion Using Maven

但是,如果我们使用 yaml 存储应用程序属性,则必须用其他分隔符替换定界符@,例如^中的pom.xml

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>2.7</version>
    <configuration>
        <delimiters>
            <delimiter>^</delimiter>
        </delimiters>
        <useDefaultDelimiters>false</useDefaultDelimiters>
    </configuration>
</plugin>

或更简单-只需在pom.xml的resource.delimiter块中替换变量propeties

<properties>
    <java.version>11</java.version>
    <resource.delimiter>^</resource.delimiter>
</properties>

然后在application.yml中使用它:

app:
  version: ^project.version^
  name: ^project.name^

答案 2 :(得分:3)

有一种更简单的方法,不需要添加application.properties或定界符更改。 只需添加带有目标build-info的插件,并使用bean BuildProperties来自动装配启动类。

<plugin>
<groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-maven-plugin</artifactId>
   <version>2.1.3.RELEASE</version>
   <executions>
     <execution>
       <goals>
         <goal>build-info</goal>
       </goals>
     </execution>
   </executions>
</plugin>

启动类将具有

@Autowired
  BuildProperties buildProperties;

稍后在@PostConstruct中,您可以调用多个方法来检索构建时间戳,版本,名称,工件等。

buildProperties.getName();
buildProperties.getVersion();
buildProperties.get("time");

info执行器将自动使用,并在检测到该信息时显示此信息,并在发现任何信息时显示git information

答案 3 :(得分:1)

这可能是因为你的主要pom并没有将spring-boot-starter-parent声明为其父pom。 因为在这种情况下,默认情况下会进行过滤,而无需明确声明过滤

我来自:

<parent>
    <groupId>com.mycompany</groupId>
    <artifactId>mycompany-parent</artifactId>
    <version>20</version>
</parent>

到:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.6.RELEASE</version>
</parent>

在我的应用程序中,主pom.xml修复了这个问题,而不必声明过滤。

答案 4 :(得分:0)

It works with @charactor.
 <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
</resource>

和...在您的 application.properties 或 appplication.yml 文件....

版本:@project.version@ 名称:@project.name@