0

I'm currently working on migrating an existing application to Spring Boot 1.2 (uses Mule 3; isn't compatible with Spring 4.2). This application contains a library-provided (that I can't modify) servlet that does the Mule bootstrap process by creating several ClasspathXmlApplicationContexts by reading some app-contained XML files with bean definitions.

My problem is that this XML files contain several placeholders that should be resolved differently based on the active profile (and I've stored those variables on an application.yml file, with different profiles), but the applicationConfig PropertySource isn't available on the StandardEnvironments created by the new application contexts.

I could transform the YML file to a .properties file and create a new PropertyPlaceholderConfigurer inside each of this XML files, pointing to the same application-#{systemProperties['spring.profiles.active']}.properties, but:

  1. I'd lose Boot's flexibility of locating the .properties file in different internal/external locations using convention and precedence, which sounds handy for an application that's gonna by migrating on different environments.

  2. If I need to add the same definition several times, I guess there's a programmatic way of doing it that I'm ignoring.

Does anybody know how could I add the applicationConfig PropertySource's content to all newly-created ApplicationContexts without having access to modify the class that creates them? Spring Boot 1.2 doesn't have the awesomeness of the EnvironmentPostProcessor to do so.

gnzlrm
  • 190
  • 1
  • 12

2 Answers2

0

For future references: I've solved this by implementing an ApplicationListener that searches all PropertySources for the applicationConfig's one and puts all it's properties on the System.getProperties() map instead, where they're resolvable by all ApplicationContexts by setting an empty on the XML files.

gnzlrm
  • 190
  • 1
  • 12
0

When you create a new Context all the property sources from the main env can be added to the newly created context using something like.

public AnnotationConfigApplicationContext createNewApplicationContext(ConfigurableEnvironment mainEnv) throws IOException {
AnnotationConfigApplicationContext newContext = new AnnotationConfigApplicationContext();
//Add scan for your packages
newContext.scan("com.abc.mycompany");
//Also Any different profile in association with new context can be added newContext.getEnvironment().addActiveProfile("newProfile");
mainEnv.getPropertySources().stream().filter(propertySource -> propertySource.getName().startsWith("applicationConfig")).forEach(newContext.getEnvironment().getPropertySources()::addLast);
newContext.refresh();
return newContext;
}

Now you can create as many contexts as you like. Also to take care of this at end of all beans creation you can you @PostConstruct and write a wrapper method that calls this new context generation function.