Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Conditional Spring configuration

Tags:

java

spring

Is it possible to use conditional expressions in a Spring config?

E.g. I'd like to define two different connectors like this:

Connector 1:

<spring:bean id="MyConnector" class="org.test.provider.DBConnector">
    <spring:property name="host" value="${my.config.host}"/>
    <spring:property name="user" value="${my.config.user}"/>
    <spring:property name="password" value="${my.config.password}"/>
</spring:bean>

Connector 2:

<spring:bean id="MyConnector" class="org.test.provider.FileSystemConnector">
    <spring:property name="path" value="${my.config.path}"/>
</spring:bean>

Then, later, use one of those like this:

<spring:bean id="LookupCommand" class="org.test.lookup.LookupCommand"
    scope="prototype">
    <spring:property name="connector" ref="MyConnector"/>
</spring:bean>

Depending on, lets say, ${my.config.connectorType} from my .cfg file, I'd like to chose/activate one of those two:

if ${my.config.connectorType} == DB then

    <spring:bean id="MyConnector" class="org.test.provider.DBConnector">
        <spring:property name="host" value="${my.config.host}"/>
        <spring:property name="user" value="${my.config.user}"/>
        <spring:property name="password" value="${my.config.password}"/>
    </spring:bean>

else

    <spring:bean id="MyConnector" class="org.test.provider.FileSystemConnector">
        <spring:property name="path" value="${my.config.path}"/>
    </spring:bean>
end
...
<spring:bean id="LookupCommand" class="org.test.lookup.LookupCommand"
    scope="prototype">
    <spring:property name="connector" ref="MyConnector"/>
</spring:bean>
like image 877
Frizz Avatar asked May 26 '14 14:05

Frizz


People also ask

What is @conditional annotation in spring boot?

Annotation Type ConditionalIndicates that a component is only eligible for registration when all specified conditions match. A condition is any state that can be determined programmatically before the bean definition is due to be registered (see Condition for details).

What is @configuration in spring boot?

Spring @Configuration annotation is part of the spring core framework. Spring Configuration annotation indicates that the class has @Bean definition methods. So Spring container can process the class and generate Spring Beans to be used in the application.

What is conditional bean in spring?

Why do we need Conditional Beans? A Spring application context contains an object graph that makes up all the beans that our application needs at runtime. Spring's @Conditional annotation allows us to define conditions under which a certain bean is included into that object graph.


2 Answers

A simple alternative solution. Give different names for each connector as below

<spring:bean id="dbConnector" class="org.test.provider.DBConnector">
    <spring:property name="host" value="${my.config.host}"/>
    <spring:property name="user" value="${my.config.user}"/>
    <spring:property name="password" value="${my.config.password}"/>
</spring:bean>

<spring:bean id="fileConnector" class="org.test.provider.FileSystemConnector">
    <spring:property name="path" value="${my.config.path}"/>
</spring:bean>

In your properties file, specify the name of the connector you wish to connect like my.config.connectorType=dbConnector

In LookupCommand bean, refer this property as below

<spring:bean id="LookupCommand" class="org.test.lookup.LookupCommand"
    scope="prototype">
    <spring:property name="connector" ref="${my.config.connectorType}"/>
</spring:bean>

Note: I initially thought of suggesting bean definition profile but you have to pass system properties -Dspring.profiles.active in your JVM. I'm trying to avoid that and in the above method you don't have the hassle to set any JVM system properties.

like image 83
Kalyan Avatar answered Oct 11 '22 11:10

Kalyan


Another alternative approach: Bean definition profiles. Have these nested <beans> elements in your XML file:

<beans profile="db1">
    <bean id="MyConnector" ...>
        ...
    </bean>
</beans>

<beans profile="db2">
    <bean id="MyConnector" ...>
        ...
    </bean>
</beans>

and add spring.profiles.active to your environment variables like this:

-Dspring.profiles.active="db1"
like image 41
Jens Hoffmann Avatar answered Oct 11 '22 10:10

Jens Hoffmann