Let's assume there are multiple Spring Boot applications having properties with @...@
placeholders referring to Maven project properties:
spring.application.name=@project.name@
version=@project.version@
...
Since it's common to all applications, it would be useful to create a custom Spring Boot starter, to prevent duplication, that would add those properties to the Environment with the lowest precedence.
In the custom starter, I added the properties to the custom.properties
file and created CustomEnvironmentPostProcessor
to load them:
public class CustomEnvironmentPostProcessor implements EnvironmentPostProcessor {
private final PropertiesPropertySourceLoader loader = new PropertiesPropertySourceLoader();
@Override
public void postProcessEnvironment(
ConfigurableEnvironment environment, SpringApplication application) {
ClassPathResource path = new ClassPathResource("custom.properties");
PropertySource<?> propertySource = loadProperties(path);
environment.getPropertySources().addLast(propertySource);
}
private PropertySource<?> loadProperties(ClassPathResource path) {
Assert.isTrue(path.exists(), () -> "Resource " + path + " does not exist");
try {
return this.loader.load("custom-properties", path).get(0);
} catch (IOException ex) {
throw new IllegalStateException("Failed to load properties configuration from " + path, ex);
}
}
}
Unfortunately, those properties are not covered by resource filtering.
The build part in the applications' pom.xml
is shown below:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
The question is is it possible to cover the starter's properties file by resource filtering? Or is there any other or better way to load properties from pom.xml
and add them to the Environment before it starts?
One possible solution to read Maven properties is to use MavenXpp3Reader
from the maven-model
dependency.
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
<version>3.8.6</version>
</dependency>
The EnvironmentPostProcessor
, which adds properties to the Spring Environment, should be defined as follows:
public class CustomEnvironmentPostProcessor implements EnvironmentPostProcessor {
private final MavenXpp3Reader reader = new MavenXpp3Reader();
@Override
public void postProcessEnvironment(
ConfigurableEnvironment environment, SpringApplication application) {
try (FileReader fileReader = new FileReader("pom.xml")) {
Model model = reader.read(fileReader);
Map<String, Object> properties = new HashMap<>();
properties.put("spring.application.name", model.getName());
properties.put("version", model.getVersion());
environment
.getPropertySources()
.addLast(new MapPropertySource("custom-properties", properties));
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
}