Reputation: 99
I read through the Spring Boot documentation for externalized configuration and I see that it automatically loads the src/main/resources/application.properties file which can be then wired to the bean properties using annotation.
However I want to have a generic PropertyHelper
class which can be used to build the java.util.Properties
with the properties in application.properties. Can this be done?
We are currently achieving this manually as below:
public class PropertyHelper {
private static Properties loadProperties() {
try {
String propsName = "application.properties";
InputStream propsStream = PropertyHelper.class
.getClassLoader().getResourceAsStream(propsName);
if (propsStream == null) {
throw new IOException("Could not read config properties");
}
Properties props = new Properties();
props.load(propsStream);
Upvotes: 4
Views: 9222
Reputation: 19918
Inject application context arguments in constructor and relay it into java.util.properties:
import java.util.Properties;
import org.springframework.boot.ApplicationArguments;
public MyComponentClass(ApplicationArguments arguments) {
Properties properties = getProperties(arguments);
}
private static Properties getProperties(ApplicationArguments arguments) {
Properties properties = new Properties();
for (String argementName : arguments.getOptionNames()) {
List<String> argumentValues = arguments.getOptionValues(argementName);
if (argumentValues.size() > 0) {
properties.put(argementName, argumentValues.get(0));
}
}
return properties;
}
Upvotes: 0
Reputation: 818
Here is how I derive a Properties object from Spring's Environment. I look for property sources of type java.util.Properties, which in my case will give me system properties and application properties.
@Resource
private Environment environment;
@Bean
public Properties properties() {
Properties properties = new Properties();
for (PropertySource<?> source : ((ConfigurableEnvironment) environment).getPropertySources()) {
if (source.getSource() instanceof Properties) {
log.info("Loading properties from property source " + source.getName());
Properties props = (Properties) source.getSource();
properties.putAll(props);
}
}
return properties;
}
Note however that the order may be significant; you would probably want to load the system properties after other properties, so they can override application properties. In that case, add some more control code using source.getName()
to pick out "systemProperties":
@Bean
public Properties properties() {
Properties properties = new Properties();
Properties systemProperties = null;
for (PropertySource<?> source : ((ConfigurableEnvironment) environment).getPropertySources()) {
if (source.getSource() instanceof Properties) {
if ("systemProperties".equalsIgnoreCase(source.getName())) {
log.info("Found system properties from property source " + source.getName());
systemProperties = (Properties) source.getSource();
} else {
log.info("Loading properties from property source " + source.getName());
Properties props = (Properties) source.getSource();
properties.putAll(props);
}
}
}
// Load this at the end so they can override application properties.
if (systemProperties != null) {
log.info("Loading system properties from property source.");
properties.putAll(systemProperties);
}
return properties;
}
Upvotes: 0
Reputation: 17085
You could create a Wrapper
around Environment, which would return a ready-to-use PropertySource
:
You would use it this way:
@PropertySource(name="myName", value="classpath:/myName.properties")
public class YourService {
@Autowired
private CustomMapProperties customMapProperties;
...
MapPropertySource mapPropertySource = customMapProperties.getMapProperties("myName");
for(String key: mapPropertySource.getSource().keySet()){
System.out.println(mapPropertySource.getProperty(key));
}
CustomMapProperties
is injected with Environment
and returns the request & loaded property file based on its name:
@Component
public class CustomMapProperties {
@Autowired
private Environment env;
public MapPropertySource getMapProperties(String name) {
for (Iterator<?> it = ((AbstractEnvironment) env).getPropertySources().iterator(); it.hasNext();) {
Object propertySource = it.next();
if (propertySource instanceof MapPropertySource
&& ((MapPropertySource) propertySource).getName().equals(name)) {
return (MapPropertySource) propertySource;
}
}
return null;
}
}
Upvotes: 1