Reputation: 153
Can I control whether a Spring bean in my application context is instantiated based on the parameter I pass to the application?
Example:
If I have spring profiles set in
ANT's build.xml jvmarg as:
-Dspring.profiles.active=P1,P2
For the below code snippet in a Configuration class:
@Bean
@Profile({"!P1", "!P2"})
public String P3() {
String s = "Check1:P3";
System.out.println(s);
return s;
}
@Bean
@Profile({"!P1", "!P3"})
public String P2() {
String s = "Check2:P2";
System.out.println(s);
return s;
}
@Bean
@Profile({"!P2", "!P3"})
public String P1() {
String s = "Check3:P1";
System.out.println(s);
return s;
}
@Bean
@Profile("P3")
public String P3_1() {
String s = "Check4:P3";
System.out.println(s);
return s;
}
@Bean
@Profile("P1")
public String P1_1() {
String s = "Check5:P1";
System.out.println(s);
return s;
}
@Bean
@Profile("P2")
public String P2_1() {
String s = "Check6:P2";
System.out.println(s);
return s;
}
I get the output as:
Check2:P2
Check3:P1
Check5:P1
Check6:P2
which is correct.
But when I set the profiles in build.xml as:
-Dspring.profiles.active=P1
Output:
Check1:P3
Check2:P2
Check3:P1
Check5:P1
But as per my expectation, I was hoping to get as output like:
Check3:P1
Check5:P1
(i.e.) only P1() bean is up at runtime.
Can anyone suggest me if that is possible with @Profiles ? I can control the beans which are up at runtime based on the exclusion rule of profiles? Or how can I achieve this?
The basic requirement is if there are 'n' beans. I can control 1 bean to be up at runtime based on the parameter I pass to the environment/server target.
I am trying to make use of a shared code(where all beans are defined) which can be used by different environments(requiring one bean each to up for a particular environment)?
Upvotes: 1
Views: 956
Reputation: 153
I was able to able to solve the problem of on-demand bootstrapping of my application serving various business through a shared orchestrating code base by blending the concept of ServiceLocatorFactoryBean and Spring Profiles.
Links: http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/config/ServiceLocatorFactoryBean.html http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-profiles.html
Spring profiles helped in creating the beans on demand as specified in the environment/application context and locator factory creating a dynamic proxy which implements that interface, delegating to an underlying BeanFactory, hence decoupling of calling code from the BeanFactory API, by using an appropriate custom locator interface
Upvotes: 0
Reputation: 2878
Probably profiles are not good for this.
You might use just ordinary properties instead.
Check @Conditional annotation (Spring 4) and even more handy @ConditionalOnExpression("${P1}") (available in Spring boot only).
Another option - some manual logic inside your @Configuration class, e.g.:
@Value("${P1}") boolean isP1;
@Bean String p1OrP2() {
return (isP1) ? "P1" : "P2";
}
This might be enough for common cases, e.g. this way you can control whether to use some feature (use a full implementation bean) or not (use some bean with a minimal behavior).
Upvotes: 1