How to mock absent bean definitions in SpringJUnit4ClassRunner? - java

I have a Spring 4 JUnit test which should verify only a particular part of my application.
#WebAppConfiguration
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("classpath:context-test.xml")
#ActiveProfiles("test")
public class FooControllerIntegrationTest {
...
}
So I don't want to configure and instantiate all those beans which are actually aren't involved into the scope of my test. For example I don't want to configure beans which are used in another controller which I am not going to test here.
However, because I don't want to narrow component-scan pathes, I get "No qualifying bean of type" exception:
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type [...
Is any way how to ignore such missed definitions if I certainly sure that they aren't involved into the functionality I am testing?

Is any way how to ignore such missed definitions if I certainly sure that they aren't involved into the functionality I am testing?
No, there is no automated or built-in mechanism for such a purpose.
If you are instructing Spring to load beans that have mandatory dependencies on other beans, those other beans must exist.
For testing purposes, the best practices for limiting the scope of which beans are active include modularization of your config (e.g., horizontal slicing that allows you to selectively choose which layers of your application are loaded) and the use of bean definition profiles.
If you're using Spring Boot, you can then also make use of "testing slices" or #MockBean/#SpyBean in Spring Boot Test.
However, you should keep in mind that it's typically not a bad thing to load beans that you are not using in a given integration test, since you are (hopefully) testing other components that in fact need those beans in other test classes within your test suite, and the ApplicationContext would then be loaded only once and cached across your different integration testing classes.
Regards,
Sam (author of the Spring TestContext Framework)

I have found a way how to automatically mock absent bean definitions.
The core idea is to create own BeanFactory:
public class AutoMockBeanFactory extends DefaultListableBeanFactory {
#Override
protected Map<String, Object> findAutowireCandidates(final String beanName, final Class<?> requiredType, final DependencyDescriptor descriptor) {
String mockBeanName = Introspector.decapitalize(requiredType.getSimpleName()) + "Mock";
Map<String, Object> autowireCandidates = new HashMap<>();
try {
autowireCandidates = super.findAutowireCandidates(beanName, requiredType, descriptor);
} catch (UnsatisfiedDependencyException e) {
if (e.getCause() != null && e.getCause().getCause() instanceof NoSuchBeanDefinitionException) {
mockBeanName = ((NoSuchBeanDefinitionException) e.getCause().getCause()).getBeanName();
}
this.registerBeanDefinition(mockBeanName, BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition());
}
if (autowireCandidates.isEmpty()) {
final Object mock = mock(requiredType);
autowireCandidates.put(mockBeanName, mock);
this.addSingleton(mockBeanName, mock);
}
return autowireCandidates;
}
}
It also should be registered by creating own AbstractContextLoader implementation, based on the GenericXmlWebContextLoader. Unfortunately the latter one has a final loadContext(MergedContextConfiguration mergedConfig) method, so it is needed to fully copy its implementation (say into class AutoMockGenericXmlWebContextLoader) with one difference:
GenericWebApplicationContext context =
new GenericWebApplicationContext(new AutoMockBeanFactory());
No it can be used in the test:
#ContextConfiguration(
value = "classpath:context-test.xml",
loader = AutoMockGenericXmlWebContextLoader.class)

If you don't narrow your component-scan, then usually you would have all the beans available to the test, EXCEPT some specific ones that become available conditionally (e.g. beans defined by spring-batch)
In this case, one option that has worked for me is to mark such dependencies and components as #Lazy. This will make sure that they will only be loaded when needed. Note that (depending on scenario) you may have to mark both the #Autowired dependency and the #Component as #Lazy

Like the OP posted, here is the annotation context equivalent to inject any mock missing beans:
context = new CustomAnnotationConfigApplicationContext(SpringDataJpaConfig.class);
public class CustomAnnotationConfigApplicationContext extends AnnotationConfigApplicationContext {
public CustomAnnotationConfigApplicationContext() {
super(new AutoMockBeanFactory());
}
public CustomAnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
}
public class AutoMockBeanFactory extends DefaultListableBeanFactory {
#Override
protected Map<String, Object> findAutowireCandidates(final String beanName, final Class<?> requiredType, final DependencyDescriptor descriptor) {
String mockBeanName = Introspector.decapitalize(requiredType.getSimpleName());
Map<String, Object> autowireCandidates = new HashMap<>();
try {
autowireCandidates = super.findAutowireCandidates(beanName, requiredType, descriptor);
} catch (UnsatisfiedDependencyException e) {
if (e.getCause() != null && e.getCause().getCause() instanceof NoSuchBeanDefinitionException) {
mockBeanName = ((NoSuchBeanDefinitionException) e.getCause().getCause()).getBeanName();
}
this.registerBeanDefinition(mockBeanName, BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition());
}
if (autowireCandidates.isEmpty()) {
System.out.println("Mocking bean: " + mockBeanName);
final Object mock = Mockito.mock(requiredType);
autowireCandidates.put(mockBeanName, mock);
this.addSingleton(mockBeanName, mock);
}
return autowireCandidates;
}
}

Related

How can I create multiple Spring beans in a #Bean-annotated method or anything similar?

In a Spring application that uses HTTP remoting, I have a service façade module configured as follows (I made the code generic to improve clarity):
#Configuration
public class MyFacadeConfig {
private HttpInvokerServiceExporter facade(Class<?> cls) {
HttpInvokerServiceExporter bean = new HttpInvokerServiceExporter();
// The service referred to by this exporter is already instantiated as another Spring bean with all its dependencies.
bean.setService(appContext.getBean(cls));
bean.setServiceInterface(cls);
return bean;
}
#Bean("/first.service")
public HttpInvokerServiceExporter firstServiceFacade() {
return facade(FirstService.class);
}
#Bean("/second.service")
public HttpInvokerServiceExporter secondServiceFacade() {
return facade(SecondService.class);
}
// ... and so on for the 37 other services
}
where FirstService and SecondService are interfaces with existing implementations whose detail is not needed here.
I have another module that defines 39 proxies (instances of HttpInvokerProxyFactoryBean) corresponding to each of my services exposed through my façade.
So far, everything works properly.
But I would like to make the code more generic, elegant, and robust while mitigating the risk of error (e.g., a bad mapping between a service and its proxy in the future). The way I would like to do this is as follows:
First, I move the façade/proxy metadata into an enumeration:
public enum ConfigBeansFacade {
FIRST("/first", FirstService.class),
SECOND("/second", SecondService.class)
// ... and so on for the 37 other services
;
private String beanName;
private Class<?> serviceInterface;
// Constructor and getters
public String getCompleteBeanName() {
return beanName + ".service";
}
}
Then the configuration of the façade would be simplified in a style similar to the following:
#Configuration
public class MyFacadeConfig {
#Autowired
private ConfigurableBeanFactory beanFactory;
#Autowired
public void configExporters() {
for (ConfigBeansFacade bean : ConfigBeansFacade.values()) {
HttpInvokerServiceExporter exp = new HttpInvokerServiceExporter();
exp.setService(beanFactory.getBean(bean.getServiceInterface()));
exp.setServiceInterface(bean.getServiceInterface());
beanFactory.registerSingleton(bean.getCompleteBeanName(), exp);
}
}
}
I tried every single recipe I found in online forums, including StackOverflow, but there are two constraints not met elsewhere:
When defining the exporters, the underlying services are other Spring beans that are instantiated, initialized, and registered with their own configuration and dependencies through the standard Spring mechanics. There is no direct class instantiation other than the exporters themselves.
I thought about grouping the exporters into a single collection as suggested by some people. The only problem is that Spring MVC uses the HttpInvokerServiceExporter Spring bean names as endpoint URIs when registering the exporters into its own configuration. I must therefore register each exporter as a “first-class citizen” bean with its own bean name into the application context.
Given these constraints, the problem I have arises in (1) when I try to retrieve the underlying services to be encapsulated into exporters: they are not necessarily ready yet, which results into UnsatisfiedDependencyExceptions.
I tried solutions with a #PostContruct-annotated method, with a BeanPostProcessor, with an #Autowired method (as shown above), nothing is working as required.
Does anyone know about a way or a technique to initialize and register multiple beans inside a single method under my constraints described above? Such a method doesn't need to be annotated with #Bean, #Autowired, or any other specific annotation, it's just an example of what I tried.
In the client module, mercifully, the HttpInvokerProxyFactoryBean instances need only the interfaces and the bean names, so constraint (1) above should not apply.
Thanks in advance for any help you can provide...
I'm not 100% I've understood what you're trying to do but I wonder if you could try autowiring a List of beans that implement an interface?
e.g.
public interface MyService {
String getKey();
void doStuff();
}
Then implement as many of these as you require
e.g.
#Component
public class FirstService implements MyService {
public String getKey() {
return "/first";
}
public void doStuff() {
...
}
}
then have a factory bean with the autowired list
#Component
public class MyServiceFactory {
private final List<MyService> services;
#Autowired
public MyServiceFactory(List<MyService> services) {
this.services = services;
}
}
To add more implementations of MyService, simply add them as #Component and Spring magically picks them up and adds them to the list.
Sometimes I find it useful to access my implementations via a Map
#Component
public class MyServiceFactory {
private final Map<String, MyService> services;
#Autowired
public MyServiceFactory(List<MyService> services) {
this.services = services
.stream()
.collect(toMap(MyService::getKey, Function.identity()));
}
public MyService getServiceByKey(String key) {
return services.get(key);
}
}
I find this keeps each implementation nice and self contained (and easy to test). Spring automatically picks up all the components that implement my interface without the factory having a huge number of imports. And I can test the factory easily by mocking the list of implementations.

Spring Bean depending on initialization of non-Spring class

Say I have some Java class named SomeClassConfig in which I want to define a dependency injection like the following;
#Configuration
public class SomeClass {
#Bean
SomeOtherClass someOtherClass() {
FactoryClass factory = UtilFactoryClass.getDefaultFactory();
return factory.create();
}
}
Here UtilFactoryClass denotes some library that allows me to create a factory class, which in turn allows me to create an instance of the object I am interested in. My problem is that the above-mentioned default factory is initialized after some time, so I would like for the bean to be instantiated / injected after the instantiation the default FactoryClass instance. Is this possible? UtilFactoryClass has no knowledge of the Spring Boot framework, and I tried to apply the #DependsOn annotation, but realized it only allows for me to depend on other Beans.
The concrete 'getDefaultFactory' method I am trying to apply is the following: Link. It is associated to a library named Keycloak. My problem is that the factory obtained from this method is null until a certain point in the life cycle of the application.
Do you mean:
#Configuration
public class SomeClass {
#Bean
SomeOtherClass someOtherClass() { //argument injection also possible
return factory().create();
}
#Bean
FactoryClass factory() {
//check/wait for condition e.g.:
while (!UtilityFactory.isInitialized()) {
try {
Thread.sleep(1000);
// better: TimeUnit.XXX.sleep(), and even better use an (spring managed) executor
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
return UtilFactoryClass.getDefaultFactory();
}
}
"Let spring manage the factory"!? ;)
For the check/wait part, see: https://www.baeldung.com/java-delay-code-execution

How to pass Spring context as a method argument?

I need some help with Spring (SpringBoot 1.3.2.RELEASE, Spring 4.3.11.RELEASE).
Use case is special and need explanations.
I've got a Spring app managing requests send by customers. In order to process these requests, we need to use services declared with #Autowired annotation. Very classic.
Recently, we decided to process new types of requests from other countries.
The point is that to face the different cases and types of requests, we decided to implement a Strategy Pattern.
-> Depending on the type of request, we execute a strategy which is selected at run time. Each strategy is contained in a concrete class and all strategies share a same Interface.
So, I had :
a main class in which requests processing was completely done. To do its job, this class used to call somes services declared with #Autowired annotation.
Now I have :
a main class in which requests processing is only initialized. To do
its job, this class will instantiate at runtime a single strategy depending on some criterias.
a IStrategy (interface) with 2 methods thats will be implemented
by my 2 concrete classes
2 concrete classes (and more to come) that will do the job. The very important point is that these concrete classes will be instantiated at runtime, AFTER the Spring context is loaded.
The problem is that after the Spring context is loaded, it's not possible anymore to use the #Autowired annotation.
All services I wanted to use in my concrete strategy classes can not be called by #Autowired any more and remain NULL.
I found a workaround by passing services I need as argument to my concrete strategy classes, but the number of services I have to pass as argument vary from one strategy to another.
I think I should pass the whole Spring context instead but I don't know how to do that. And I also don't know how I could access to all annotated services from the context.
PS : I do not show lines of code because I think there's no need actually. If you consider it would be more explicit with code, I will send some.
Thanx by advance.
Instead of declaring the services as bean, you should declare a factory to map the dependencies, it will inspect the request before returning the concrete instance of the service to the injector.
take a look here:
https://grokonez.com/spring-framework/spring-core/use-spring-factory-method-create-spring-bean
You can use below class to get Application Context and Beans statically
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;
#Service
public class BeanUtil implements ApplicationContextAware {
private static ApplicationContext context;
#Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
}
Hello to all of you who answered me very quickly.
First of all, I have to apologize for answering so lately to all your comments. Last sprint was a big load and the new one is not better ^^
My need was to create on object after the Spring context has finished to create and load all parts of the app.
As part of a Strategy pattern, I have to instanciate a class at runtime depending on some values found in the request file I have to process. This class needs many services declared with the #Autowired annotation, but all the autowired objects remained 'null' because called after the context was loaded.
Here is the code I first wanted to use.
It was OK without Spring.
Function<Document, IStrategy> func = doc -> {
String strategyToApply = "";
IStrategy strategy = null;
switch(doc.getPlace()) {
case "Paris":
strategyToApply = "strategies_classes.ProcessParis";
break;
case "New York":
strategyToApply = "strategies_classes.ProcessNewYork";
break;
}
case "Roma":
...
try {
**Class<?> classToUse = Class.forName(strategyToApply);
strategy = (IStrategy) classToUse.newInstance();**
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return strategy;
};
Consumer<Document> consumerStrategy = doc -> {
IStrategy strategy = func.apply(doc);
strategy.bookRequest(doc);
};
documents.stream()
.forEach(consumerStrategy);
I finally found THE magic object. It is a good workaround when Spring object's lifecycle is not compliant with our own conception.
To use it, you just have to declare it with #Autowired :
#Autowired
private AutowireCapableBeanFactory autowireBeanFactory;
Note that the AutowireCapableBeanFactory is a Spring object you don't need to declare anywhere else !!
Then, to use it, simple (I designed a brand new service very different from what you saw above, but it's doing the same) :
public <T> T getStrategyToUse(Entity bookingCtr, Funder funder, StrategyEnum strategy) throws FunctionalException {
String strategyToApply = null;
strategyToApply = strategyDao.getClassToApply(bookingCtr, funder, strategy);
Class<?> classToUse;
try {
classToUse = Class.forName(strategyToApply);
T strat = (T) **autowireBeanFactory.getBean**(classToUse);
return (T) strat;
} catch (ClassNotFoundException e) {
LOGGER.error("The indicated Strategy class was not found", e);
}
return null;
}
When loaded at runtime, the chosen class will be instanciated without any problem and ALL of its autowired objects won't be null anymore.
I hope this will help.

Inheritance with Spring Java Config uses different bean

The following example shows explicit wiring of dependencies using spring java config that results in a different bean being wired in while using and interface for a spring configuration class.
This seems like it shouldn't occur or at least give the normal warning that there are two beans as candidates for autowiring and it doesn't know which to select.
Any thoughts on this issue? My guess is there is no real name spacing between configuration classes as is implied by the syntax "this.iConfig.a()" Could this be considered a bug (if only for not warning about the 2 candidate beans)?
public class Main
{
public static void main( final String[] args )
{
final ApplicationContext context = new AnnotationConfigApplicationContext( IConfigImpl.class, ServiceConfig.class );
final Test test = context.getBean( Test.class );
System.out.println( test );
}
}
public class Test
{
private final String string;
public Test( final String param )
{
this.string = param;
}
public String toString()
{
return this.string;
}
}
#Configuration
public interface IConfig
{
#Bean
public String a();
}
#Configuration
public class IConfigImpl implements IConfig
{
#Bean
public String a()
{
return "GOOD String";
}
}
#Configuration
public class ServiceConfig
{
#Autowired
IConfig iConfig;
#Bean
Test test()
{
return new Test( this.iConfig.a() );
}
#Bean
String a()
{
return "BAD String";
}
}
In this case, I would expect to have "GOOD String" to be always be wired in the Test object, but flipping the order of IConfigImpl.class, ServiceConfig.class in the context loader changes which string is loaded.
Tested with Spring 4.0.7
EDIT: Further testing shows this has nothing to to with inherented configs. Same thing results if you drop the IConfig interface.
I believe this was a behavior of Spring for years.
If you redefine a bean, the one that is being loaded as last wins.
Another question would be how to control the order of bean loading when java configs are used. Check out this article http://www.java-allandsundry.com/2013/04/spring-beans-with-same-name-and.html which shows you how to do the ordering by using #Import of the other Spring java config.
The solution is actually simple - if you need to override a previously
defined bean(without say the flexibility of autowiring with a
different bean name), either use the XML bean configuration for both
the bean being overridden and the overriding bean or use the
#Configuration. XML bean configuration is the first example in this
entry, the one with #Configuration would be something like this:
#Configuration
public class Context1JavaConfig {
#Bean
public MemberService memberService() {
return new MemberSvcImpl1();
}
}
#Configuration
#Import(Context1JavaConfig.class)
public class Context2JavaConfig {
#Bean
public MemberService memberService() {
return new MemberSvcImpl2();
}
}
Stepan has mentioned the issue of order. The following is about your comment on their answer
Overriding beans of the same name makes sense, but in this case, I'm
specifically referencing the bean as specified in the iConfig
configuration. I would expect to get the one specified there.
In order to implement #Configuration and the caching of beans so that calls like
#Configuration
class Example {
#Bean
public UncaughtExceptionHandler uncaughtExceptionHandler() {
return (thread, throwable) -> System.out.println(thread + " => " + throwable.getMessage());
}
#Bean
#Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public Thread newThread() {
Thread thread = new Thread();
thread.setUncaughtExceptionHandler(uncaughtExceptionHandler()); // <<<<<< allowing this
return thread;
}
}
Spring actually uses CGLIB to create a proxy subtype of the #Configuration annotated class. This proxy maintains a reference to the backing ApplicationContext and uses that to resolve a bean.
So the call in your example
return new Test(this.iConfig.a());
isn't really invoking IConfigImpl#a(). It invokes this code (as of 4.2) from the proxy interceptor. The code uses the corresponding Method to determine the target bean name and uses the ApplicationContext's BeanFactory to resolve the bean. Since the bean definition for a bean named a has already been overriden, that new bean definition gets used. That bean definition is using the ServiceConfig#a() method as its factory method.
This is described in the documentation, here
All #Configuration classes are subclassed at startup-time with CGLIB.
In the subclass, the child method checks the container first for any
cached (scoped) beans before it calls the parent method and creates a
new instance.
Could this be considered a bug [...]?
I don't believe so. The behavior is documented.

Java Based Configuration and factory pattern

Suppose I've a class Fruit and it's two subclasses - Apple and Grape:
class Fruit {
public void grind() { }
}
class Apple extends Fruit { }
class Grape extends Fruit { }
In spring properties file, I've a property that decides which bean to register at startup. At a time, I'll only have either Apple or Grape instance registered as a bean. The property is:
# This can be either apple or grape
app.fruit = apple
In the Java configuration file, I'm binding a String attribute using #Value with this property, and based on that, I'll create appropriate instance. I'm trying to use factory pattern here. So, I've a FruitFactory like this:
class FruitFactory {
private Map<String, Fruit> map = new HashMap<String, Fruit>();
public FruitFactory() {
map.put("apple", new Apple());
map.put("grape", new Grape());
}
public Fruit getFruit(String fruit) {
return map.get(fruit);
}
}
And here's my spring configuration class:
class SpringConfig {
#Value("${app.fruit}")
private String fruitType;
#Bean
public FruitFactory fruitFactory() {
return new FruitFactory();
}
#Bean
public Fruit getFruit() {
return fruitFactory().getFruit(fruitType);
}
}
So, here're my few questions:
Will the instances stored in the map inside the factory be spring managed bean? Is there any issue with the implementation? I've tried it, and it is working fine, and I'm confused whether the instances are really spring managed.
I was trying to implement it in a better way, so that when a new fruit comes, I don't have to modify my factory. On way is to provide a register() method in factory and let all the Fruit subclasses invoke it. But the issue is when and how the subclasses will be loaded? I'll not be using the classes, not before putting their instances into the map. Can anyone suggest a better way?
Edit:
As suggested in comment and answer, I've tried using #Profile instead of factory pattern. But I'm facing some issues in that. Here's what I've:
#Configuration
#Profile("apple")
class AppleProfile {
#Bean
public Fruit getApple() {
return new Apple();
}
}
#Configuration
#Profile("grape")
class GrapeProfile {
#Bean
public Fruit getGrape() {
return new Grape();
}
}
And in a ServletListener, I've set the active profile:
class MyServletListener implements ServletContextListener {
#Value("${app.fruit}")
private String fruitType;
public void contextInitialized(ServletContextEvent contextEvent) {
// Get Spring Context
WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(contextEvent
.getServletContext());
context.getAutowireCapableBeanFactory().autowireBean(this);
ConfigurableEnvironment configEnvironment = (ConfigurableEnvironment) context.getEnvironment();
logger.debug("0;Setting Active Profile: " + cacheRetrievalMode);
configEnvironment.setActiveProfiles(cacheRetrievalMode);
}
}
This is properly setting the active profile, which I can see. The only issue is, the listener is declared before the ContextLoaderListener, and by the time this is executed, the beans are already been created. Is there any alternative?
Will the instances stored in the map inside the factory be spring
managed bean?
Making the FruitFactory a managed bean
#Bean
public FruitFactory fruitFactory() {
return new FruitFactory();
}
doesn't make any of the objects it's referring to managed beans. However, this
#Bean
public Fruit getFruit() {
return fruitFactory().getFruit(fruitType);
}
does make that one returned Fruit a managed bean. #Bean marks a method as a bean definition and bean factory (it creates the bean). The object you return will be managed by Spring's bean life cycle.
Is there any issue with the implementation?
It seems weird that you're creating a FruitFactory bean but also a Fruit from that same FruitFactory. Are you even going to inject the FruitFactory elsewhere in the application?
I was trying to implement it in a better way, so that when a new fruit
comes, I don't have to modify my factory
Seriously, your factory is messing everything up. Spring already does its job, and more! Annotations make your life easier. You can give an identifier to the #Bean. You can qualify the bean with #Qualifier (and then also qualify the injection target with #Qualifier). You can set a #Profile for when and under which conditions the bean should be initialized.
But the issue is when and how the subclasses will be loaded? I'll not
be using the classes, not before putting their instances into the map.
Can anyone suggest a better way?
You can use bean initMethods, which you specify as a #Bean annotation attribute, or a #PostConstruct annotated method to do post-initialization logic. You can use these to register the beans with the factory, which you'll have injected (but that design doesn't sound right to me, you'd have to show us more.)
You should also look into InitializingBean and FactoryBean.
For setting the active profile, one possibility is to do the following. Create an ApplicationContextInitializer which sets the active profile by reading from a .properties file. You won't be able to use #PropertySources here because this isn't a bean.
Something like
public class ProfileContextInitializer implements
ApplicationContextInitializer<ConfigurableApplicationContext> {
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
PropertySource<Map<String, Object>> source = null;
try {
source = new ResourcePropertySource("spring.properties");
String profile = (String) source.getProperty("active.profile");
System.out.println(profile);
ConfigurableEnvironment env = applicationContext.getEnvironment();
env.setActiveProfiles(profile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
You can register this in your deployment descriptor
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.yourapp.ProfileContextInitializer</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
When the ContextLoaderListener is created, it will pick up and instantiate your class and call its initialize method. This is done before the WebApplicationContext is refreshed.
You should probably just set a VM argument for the active profile and avoid all of this.

Categories

Resources