Не удается получить свойство maven project.version в приложении Spring с @Value

Как получить свойство maven project.version в приложении Spring Boot с аннотацией @Value?

Ответ 1

После некоторых исследований и испытаний о том, как получить версию проекта maven в приложении загрузки Spring, я не мог найти для меня ничего работающего.

Использование манифеста окончательно является гнилым путем из-за проблем загрузчика классов, т.е. получает первый манифест 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:

  [email protected]@
  [email protected]@
  [email protected]@

Обратите внимание на @свойство @вместо ${property}. в файле application.properties.

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;

Примерный проект доступен здесь.

Ответ 2

Чтобы получить доступ к свойствам Maven в приложении Spring Boot, все, что нам нужно, это сопоставить их с разделителем @ в application.properties следующим образом:

[email protected]@
[email protected]@

Затем используйте их в приложении как обычные свойства, например:

@Service
public class SomeService {

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

   // other stuff
}

Источник: автоматическое расширение свойства с помощью Maven

Но если мы используем yaml для хранения свойств приложения, мы должны заменить delimiter @ другим, например ^ в нашем 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>

Или еще проще - просто заменить переменную resource.delimiter в propeties блока вашего pom.xml:

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

Затем используйте его в application.yml:

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

Ответ 3

Есть более простой способ сделать это, не нужно добавлять application.properties или изменения разделителя. Просто добавьте плагин с информацией о цели сборки и класс запуска Autowire с компонентом 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, если он ее найдет.

Ответ 4

Это, вероятно, потому, что ваш основной 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>

В моем приложении main pom.xml исправил проблему, не объявляя фильтрацию.