Условная конфигурация Spring

Можно ли использовать условные выражения в конфигурации Spring?

например. Я бы хотел определить два разных разъема:

Коннектор 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>

Разъем 2:

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

Затем, воспользуемся одним из следующих способов:

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

В зависимости от, скажем, ${my.config.connectorType} из моего .cfg файла, я бы хотел выбрать/активировать один из двух:

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>

Ответ 1

Простое альтернативное решение. Дайте разные имена для каждого коннектора, как показано ниже

<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>

В вашем файле свойств укажите имя соединителя, который вы хотите подключить, например my.config.connectorType = dbConnector

В LookupCommand bean обратитесь к этому свойству ниже

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

Примечание. Первоначально я думал о том, что предлагаю bean профиль определения, но вам нужно передать системные свойства -Dspring.profiles.active в вашей JVM. Я пытаюсь избежать этого, и в приведенном выше методе у вас нет хлопот, чтобы установить какие-либо свойства системы JVM.

Ответ 2

Другой альтернативный подход: Bean профили определения. Имейте эти вложенные элементы <beans> в ваш XML файл:

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

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

и добавьте spring.profiles.active к следующим переменным среды:

-Dspring.profiles.active="db1"

Ответ 3

Просто создайте 2 разных файла свойств. Пусть говорят, что у них есть имя DB.properties и filesystem.properties. После этого с помощью property-placeholder вы можете ссылаться на свои файлы свойств следующим образом:

 <context:property-placeholder location="classpath*:META-INF/config/${my.config.connectorType}.properties"/>

Если вы запустите свое приложение с параметром JVM '-Dmy.config.connectorType = DB', тогда будет загружен файл DB.properties.

<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

Ответ 4

Для тех, кто все еще ищет решение, я чувствую, что этот является ответом, который наиболее близок к желаемому поведению - с использованием тернарного оператора в определении bean.