Search code examples
javaspringtomcatspring-bootspring-boot-starter

Spring boot starter web - make a configuration bean that alters properties initialized first


I am using embedded tomcat in my spring boot application. My requirement is to read all configuration properties from db as well as property files.

I managed to read properties from db and append the properties to MutablePropertySources with a @Configuration bean as follows:

@Configuration
public class PropertiesConf {

    @Autowired
    private Environment        env;

    @Autowired
    private ApplicationContext appContext;

    @PostConstruct
    public void init() {
        MutablePropertySources propertySources = ((ConfigurableEnvironment) env).getPropertySources();
        ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<>();

        DataSource ds = (DataSource) appContext.getBean("confDBBeanName");
        JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);

        //read config elements from db
        //List<IntegraProperties> list = ..

        list.forEach(entry -> map.put(entry.getKey(), entry.getValue()));
        MapPropertySource source = new MapPropertySource("custom", map);
        propertySources.addFirst(source);
    }

}

The problem is that this config is initialized after servlets (cxf servlet for example) are registered. The folowing config is read from cxf.path=/api2 from my application.properties file:

2017-11-10 09:41:41.029 INFO 7880 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'CXFServlet' to [/api2/]*

As you can see, by the time I add the configuration properties, it is too late. Some initializations take place before I add my config .

How can I make sure my bean (PropertiesConf) initializes first during start up and alters properties so that they are system wide applicable to all beans?

Currently I am adding the following DependsOn annotation to all my beans which is very nasty...

 @DependsOn("propertiesConf")

But still I have a problem with servlets and etc..

What is the correct spring way to do this


Solution

  • Probably you are looking for the EnvironmentPostProcessor.

    It makes it possible to change Environment before the application context is started and I believe it's the most clearer way to do that.

    Here is a tutorial to help you to get started: https://blog.frankel.ch/another-post-processor-for-spring-boot/#gsc.tab=0