在spring中有条件地初始化类

时间:2014-06-25 13:11:32

标签: java spring

我有一项涉及单一来源的服务。

<bean id="XYZService" class="com.services.impl.DataService1">
    <constructor-arg ref="DataSource1" />
</bean>

<bean id="DataSource1" class="com.source.impl.DataSource1">
        <constructor-arg ref="DBDataSource"/>
        <constructor-arg value="xyz"/>      
</bean>

<bean id="DataSource2" class="com.source.impl.DataSource2">
        <constructor-arg ref="MsgDataSource"/>
        <constructor-arg value="xyz"/>      
</bean>

现在,如果我想执行条件检查,我的服务应该能够根据下面的输入变量来监听特定的源。

<bean id="XYZService" class="com.services.impl.DataService1">
    <constructor-arg ref=" $VARIABLE == true ? DataSource1 : DataSource2" />
</bean>

我确实尝试过SPEL然而没有运气。我是春天的初学者。任何帮助将不胜感激。 感谢。

3 个答案:

答案 0 :(得分:2)

有很多解决方案。这里有两个:您可以使用配置文件。定义两个配置文件,定义具有相同名称但不同配置文件的DataSource bean。 (docs

或者,您可以使用单个bean和静态工厂方法(docs)。

<bean id="DataSource" class="com.source.impl.DataSourceFactory"
    factory-method="createInstance"/>

DataSourceFactory.createInstance()内,您可以检查标志,然后在普通Java中创建正确的数据源。

后者有点容易理解,IMO。使用配置文件允许您将所有内容保存在XML中(但您应该考虑切换到Java配置)。配置文件的缺点是你不能忘记激活至少一个未定义的bean。

第三种选择是使用三个XML文件,然后修改将文件传递给ApplicationContext时应解析的XML文件列表。但这只有在您控制了这部分代码时才有效。

答案 1 :(得分:2)

假设您使用的是Spring 3.1或更高版本,Spring Profiles可能是最佳解决方案。

使用Production和Dev / QA环境的示例,常见的bean声明进入共享文件

<beans>
  <bean id="XYZService" class="com.services.impl.DataService1">
    <constructor-arg ref="DataSource" />
  </bean>
</beans>

单独的配置包含生产参考

<beans profiles="prod">
  <bean id="DataSource" class="com.source.impl.DataSource1">
    <constructor-arg ref="DBDataSource"/>
    <constructor-arg value="xyz"/>      
  </bean>
</beans>

另一个包含dev引用

<beans profile="dev">
  <bean id="DataSource" class="com.source.impl.DataSource2">
    <constructor-arg ref="MsgDataSource"/>
    <constructor-arg value="xyz"/>      
  </bean>
</beans>

要激活给定的配置文件,请将-Dspring.profiles.active=prod添加到JVM参数

您可以找到更多信息here

另一种方法使用工厂方法。

<bean id="DataSource" class="com.source.impl.DataSourceFactory" factory-method="getInstance">
    <constructor-arg value="#{VARIABLE}" />
</bean>

上面的片段假定您希望工厂方法explcitly调用每个服务的构造函数。如果您设置使用Spring创建实例,则可以将每个数据源实现作为构造函数参数传递,并将构造函数方法用作简单的调度程序。

答案 2 :(得分:1)

你需要这样的东西:

<constructor-arg 
     ref="#{systemProperties.variable == 'true' ? 'DataSource1' : 'DataSource2'}" />

其中&#34;变量&#34;设置为-Dvariable=true