Tag Archives: Software Development

Managed configuration in Spring

The Spring Framework offers many options to configure your applications. Most of these options, however depend on a fixed location for your properties file. Though having a fixed location offers a lot of convenience, sometimes this is not what you want.
For a reason project I investigated a method to allow early checking for the configuration. I found that Spring Framework offers a ApplicationContextInitializer that allows you to inject custom initialisation code early in the wiring of the context. This simple example shows how to set it based on a system property and check that the file is readable.


public class PropertiesInitializer implements ApplicationContextInitializer<ConfigurableWebApplicationContext> {
    /**
     * A logger instance used for logging messages.
     */
    private static final Logger logger = LoggerFactory.getLogger(PropertiesInitializer.class);
    private static final String CONFIG_PATH = "WEBCONFIG_LOCATION";
    
    @Override
    public void initialize(ConfigurableWebApplicationContext ctx) {
        final String userLocation = System.getProperty(CONFIG_PATH);
        if (userLocation != null) {
            Path propertiesFile = Paths.get(userLocation);
            
            if (propertiesFile.toFile().canRead()) {

                final Properties userProperties = new Properties();
                try (Reader propertiesReader = Files.newBufferedReader(propertiesFile, StandardCharsets.UTF_8)) {
                    userProperties.load(propertiesReader);
                    final PropertiesPropertySource ps = new PropertiesPropertySource("USER_PROPERTIES", userProperties);
                    ctx.getEnvironment().getPropertySources().addFirst(ps);
                } catch (final IOException ex) {
                    logger.warn("Exception while reading the properties", ex);
                }
            } else {
                logger.warn("The file {} does not exist.", userLocation);
            }
        } else {
            logger.info("The Java system property {} was not set."
                    + " You can set it to the location of a properties file to override the default configuration.",
                    CONFIG_PATH);
        }
    }
}

This technique however allows to do a lot more than that. For instance you could do extensive validation on your properties: are all properties set; are file locations valid; is the database readable; etc. The advantage of checking this yourself is that you can fail early with a clear error message instead of making the administrator go throw a long list of exceptions to find out what’s wrong.

The complete code for this example project can be found in my github repository: https://github.com/djvanenckevort/allthingsdigital/