【发布时间】:2016-12-23 08:41:11
【问题描述】:
如何在带有@Value 注解的 Spring Boot 应用程序中获取 maven project.version 属性?
【问题讨论】:
标签: maven spring-boot
如何在带有@Value 注解的 Spring Boot 应用程序中获取 maven project.version 属性?
【问题讨论】:
标签: maven spring-boot
在对如何在 SpringBoot 应用程序中获取 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>
然后可以像这样在 Spring 中使用 @Value 访问这些属性:
@Value("${application.name}")
private String applicationName;
@Value("${build.version}")
private String buildVersion;
@Value("${build.timestamp}")
private String buildTimestamp;
【讨论】:
build.timestamp=@maven.build.timestamp@。
application.yml。当您也想为那个启用过滤时,您需要一个类似于docs.spring.io/spring-boot/docs/current/reference/html/… 中提到的testResources 部分
要在 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 的 propeties 块中的变量 resource.delimiter:
<properties>
<java.version>11</java.version>
<resource.delimiter>^</resource.delimiter>
</properties>
然后在你的属性文件中使用它,例如:
app:
version: ^project.version^
name: ^project.name^
【讨论】:
@ 符号替换为 ^,否则 Spring Cloud Config Server 无法正确提供带有这些分隔符的 YAML 文件。
有一种更简单的方法可以做到这一点,不需要添加 application.properties 或分隔符更改。 只需添加带有目标构建信息的插件和带有 bean BuildProperties 的 Autowire 启动类。
<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的启动类中,您可以调用多个方法来检索构建时间戳、版本、工件名称、团体等
private static final Logger LOGGER = LoggerFactory.getLogger(YourSpringApplication.class);
@Autowired
BuildProperties buildProperties;
public static void main(String[] args) {
SpringApplication.run(YourSpringApplication.class, args);
}
@PostConstruct
private void logVersion() {
LOGGER.info(buildProperties.getName());
LOGGER.info(buildProperties.getVersion());
LOGGER.info(buildProperties.get("time"));
LOGGER.info(buildProperties.getGroup());
}
info 执行器将自动使用并在检测到此信息时显示此信息,并在发现时显示git information。
【讨论】:
Consider revisiting the conditions above or defining a bean of type 'org.springframework.boot.info.BuildProperties' in your configuration.
这可能是因为您的主 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 中修复了该问题,而无需声明过滤。
【讨论】:
It works with @charactor.
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
并且...在您的 application.properties 或 appplication.yml 文件中...
版本:@project.version@ 名称:@project.name@
【讨论】: