On a project I'm currently working on we have the need for multiple profiles, i.e. "default" and "test". To solve this, we've implemented a main context class, ApplicationContext.java, with 2 public static inner classes: one of them defines the default profile, the other defines the test profile. Our web.xml is set to target ApplicationContext.java.
Code as follows:
@Configuration
//import common beans
public class ApplicationContext {
@Configuration
@Profile("default")
public static class DefaultContext {
//default beans
}
@Configuration
@Profile("test")
public static class TestContext {
//test beans
}
}
My problem with this is that the main context class, ApplicationContext.java, is in the production environment (i.e. src/main/java) with references to files in the test environment. If there is a better way to define these profiles without introducing this dependency from production code to test code, that would of course be preferable.
We`ve tested these cases with a jetty instance in a test class, started from a main method. This instance is run with the following command:
System.setProperty("spring.profiles.active", "test");
If all the beans are common between your profiles (that is, both DefaultContext
and TestContext
contains the same bean definitions), define an interface for the dependencies, e.g:
public interface SystemConfiguration {
public DataSource getDataSource();
public SomeService getService();
}
Then implement each profile with this interface:
@Profile("production")
@Configuration
public class ProductionConfiguration implements SystemConfiguration {
public DataSource getDataSource() {
// create and return production datasource
}
public SomeService getService() {
// Create and return production service
}
}
And then do the same for test.
@Profile("test")
@Configuration
public class TestConfiguration implements SystemConfiguration {
public DataSource getDataSource() {
// create and return dummy datasource
}
public SomeService getService() {
// Create and return dummy service
}
}
Then you can inject this into your main configuration:
@Configuration
public class ApplicationContext {
@Autowired
private SystemConfiguration systemConfiguration;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With