granadaCoder
granadaCoder

Reputation: 27862

SpringBoot and use / load a dynamic "applicationContext.xml" instead of hard coded one

I've seen a hundred examples of this:

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
@ImportResource("classpath:applicationContext.xml")
public class MySpringBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class, args);
    }
}

And I have been on a rabbit trail for many hours now.

I am building a framework....and I need load (a handful of dependencies, not all of them...) from the xml dependency injection file (aka, "beans") :

applicationContext.xml

and I need to name to be dynamic, not hard coded.

String myValue = "DefaultEnvVarValue";
String envValue = System.getenv("MYENVVARIABLENAME");
if (null != envValue )
{
     myValue=envValue;
}
String topLevelAppContextFileName = "applicationContext." + myValue + ".xml";

Without springboot, I would do this:

 ApplicationContext context = new ClassPathXmlApplicationContext(topLevelAppContextFileName);

Is there a way to pull this off with SpringBoot?

I found PropertySourcesPlaceholderConfigurer for property files, but cannot find anything for the dependency injection.

Sidenote:

Before I get a "xml bad" comment, most of my dependencies are annotation based. But I'm making a framework for others to use, and therefore I need a handful of them to be xml-driven.....aka, I have a legit reason to have some of the DI be xml driven.

Upvotes: 3

Views: 1194

Answers (2)

granadaCoder
granadaCoder

Reputation: 27862

For future readers, I ended up doing this:

@SpringBootApplication
@ImportResource({"classpath*:applicationContext.xml"})

public class MySpringBootApplication { 


    public static void main(String[] args) {
        try {

            URL resource = MySpringBootApplication.class.getResource("/applicationContext.xml");
            if (null == resource || StringUtils.isBlank(resource.getPath())) {
                throw new FileNotFoundException("applicationContext.xml not found.  The entry dependency injection file must be applicationContext.xml");
            }

            org.springframework.context.ConfigurableApplicationContext applicationContext = SpringApplication.run(MySpringBootApplication.class, args);

And then I put the "dynamic" part in the inside applicationContext.xml file.

Note the ":" delimiter that will allow a default value if the environment variable does not exist.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util.xsd">

    <import resource="projectContext.${MYENVVARIABLENAME:DefaultEnvVarValue}.xml"/>

That was simpler to implement, even though I technically have 2 files, instead of one.

So if the environment variable does not exist, it will default to importing the second file called:

projectContext.DefaultEnvVarValue.xml

Upvotes: 0

Ivan Furdek
Ivan Furdek

Reputation: 914

This could work -

Config

public class DemoApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

     @Override
     public void initialize(ConfigurableApplicationContext ac) {
      ac = new ClassPathXmlApplicationContext(topLevelAppContextFileName);
     }
}

Main

    public static void main(String args[]) {
         new SpringApplicationBuilder(Application.class)
            .initializers(new DemoApplicationContextInitializer())
            .run(
    }

Upvotes: 0

Related Questions