Reputation: 2544
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>
Upvotes: 15
Views: 24543
Reputation: 1742
For anyone still looking for a solution, I feel this is an answer that speaks closest to the desired behaviour - using a ternary operator in the bean definition.
Upvotes: 1
Reputation: 6801
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"
Upvotes: 4
Reputation: 1909
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.
Upvotes: 7
Reputation: 2801
Just create 2 different property files. Let's say they have name DB.properties
and filesystem.properties
. After that by using property-placeholder
you can refer to your property files by this:
<context:property-placeholder location="classpath*:META-INF/config/${my.config.connectorType}.properties"/>
If you start your application with '-Dmy.config.connectorType=DB' JVM parameter, then DB.properties
file will be loaded.
<spring:bean id="MyDbConnector" class="org.test.provider.DBConnector" lazy-init="true">
<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="MyFileSystemConnector" class="org.test.provider.FileSystemConnector" lazy-init="true">
<spring:property name="path" value="${my.config.path}"/>
</spring:bean>
<alias name="${my.connector}" alias="MyConnector"/>
<spring:bean id="LookupCommand" class="org.test.lookup.LookupCommand"
scope="prototype">
<spring:property name="connector" ref="MyConnector"/>
</spring:bean>
DB.properties
:
my.connector=MyDbConnector
filesystem.properties
:
my.connector=MyFileSystemConnector
Upvotes: 1