Let's imagine that we have an existing configuration setup that uses a popular Apache Commons Configuration framework and stores the configuration data in XML files:
- To mimic our supposed pre-existing configuration system, add the following content to the dependencies section in the build.gradle file:
dependencies { ... compile project(':db-count-starter') compile("commons-configuration:commons-
configuration:1.10") compile("commons-codec:commons-codec:1.6") compile("commons-jxpath:commons-jxpath:1.3") compile("commons-collections:commons-collections:3.2.1") runtime("com.h2database:h2") ... }
- Follow this up by creating a simple configuration file named commons-config.xml in the src/main/resources directory at the root of our project with the following content:
<?xml version="1.0" encoding="ISO-8859-1" ?> <config> <book> <counter> <delay>1000</delay> <rate>${book.counter.delay}0</rate> </counter> </book> </config>
- Next, we will create the PropertySource implementation file named ApacheCommonsConfigurationPropertySource.java in the src/main/java/org/test/bookpub directory at the root of our project with the following content:
public class ApacheCommonsConfigurationPropertySource
extends EnumerablePropertySource<XMLConfiguration> { private static final Log logger = LogFactory.getLog(
ApacheCommonsConfigurationPropertySource.class); public static final String
COMMONS_CONFIG_PROPERTY_SOURCE_NAME = "commonsConfig"; public ApacheCommonsConfigurationPropertySource(
String name, XMLConfiguration source) { super(name, source); } @Override public String[] getPropertyNames() { ArrayList<String> keys =
Lists.newArrayList(this.source.getKeys()); return keys.toArray(new String[keys.size()]); } @Override public Object getProperty(String name) { return this.source.getString(name); } public static void addToEnvironment(
ConfigurableEnvironment environment, XMLConfiguration
xmlConfiguration) { environment.getPropertySources().addAfter(
StandardEnvironment.
SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, new
ApacheCommonsConfigurationPropertySource( COMMONS_CONFIG_PROPERTY_SOURCE_NAME, xmlConfiguration)); logger.trace("ApacheCommonsConfigurationPropertySource
add to Environment"); } }
- We will now create the EnvironmentPostProcessor implementation class so as to bootstrap our PropertySource named ApacheCommonsConfigurationEnvironmentPostProcessor.java in the src/main/java/org/test/bookpub directory at the root of our project with the following content:
package com.example.bookpub;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.XMLConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
public class ApacheCommonsConfigurationEnvironmentPostProcessor implements EnvironmentPostProcessor {
@Override
public void postProcessEnvironment( ConfigurableEnvironment environment, SpringApplication application) {
try {
ApacheCommonsConfigurationPropertySource .addToEnvironment(environment,
new XMLConfiguration("commons- config.xml"));
} catch (ConfigurationException e) {
throw new RuntimeException("Unable to load commons-config.xml", e);
}
}
}
- Finally, we will need to create a new directory named META-INF in the src/main/resources directory at the root of our project and create a file named spring.factories in it with the following content:
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=
com.example.bookpub.ApacheCommonsConfigurationEnvironmentPostProcessor
- With the setup done, we are now ready to use our new properties in our application. Let's change the configuration of the @Scheduled annotation for our StartupRunner class located in the src/main/java/org/test/bookpub directory at the root of our project, as follows:
@Scheduled(initialDelayString = "${book.counter.delay}",
fixedRateString = "${book.counter.rate}")
- Let's build the application by running ./gradlew clean bootJar and start it by running ./build/libs/bookpub-0.0.1-SNAPSHOT-exec.jar --spring.profiles.active=logger in order to ensure that our StartupRunner class is still logging the book count every ten seconds, as expected.