1

假设,我的 Spring xml 中有以下 bean:

<bean id="mqConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
    <property name="hostName" value="${host}"/>
    <property name="port" value="${mq.port}"/>
</bean>

<bean id="jmsQueueConnectionFactory"
      class="org.springframework.jms.connection.SingleConnectionFactory">
    <property name="targetConnectionFactory" ref="mqConnectionFactory"/>
</bean>

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="jmsQueueConnectionFactory"/>
</bean>

我需要向不同的主机发送消息,但我不想定义多个连接工厂 bean。

指定这样的主机会很棒:

class A {
    @Autowired(host="host1")
    private JmsTemplate jmsTemplate;
}

class B {
    @Autowired(host="host2")
    private JmsTemplate jmsTemplate;
}

更新:

我可以创建以下配置:

<bean id="mqConnectionFactory1" class="com.ibm.mq.jms.MQQueueConnectionFactory">
    <property name="hostName" value="${host1}"/>
    <property name="port" value="${mq.port}"/>
</bean>

<bean id="mqConnectionFactory2" class="com.ibm.mq.jms.MQQueueConnectionFactory">
    <property name="hostName" value="${host2}"/>
    <property name="port" value="${mq.port}"/>
</bean>

<bean id="jmsQueueConnectionFactory1"
      class="org.springframework.jms.connection.SingleConnectionFactory">
    <property name="targetConnectionFactory" ref="mqConnectionFactory1"/>
</bean>

<bean id="jmsQueueConnectionFactory2"
      class="org.springframework.jms.connection.SingleConnectionFactory">
    <property name="targetConnectionFactory" ref="mqConnectionFactory2"/>
</bean>

<bean id="jmsTemplate1" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="jmsQueueConnectionFactory1"/>
</bean>

<bean id="jmsTemplate2" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="jmsQueueConnectionFactory2"/>
</bean>

然后:

class A {
    @Resource("jmsTemplate1")
    private JmsTemplate jmsTemplate;
}

class B {
    @Resource("jmsTemplate2")
    private JmsTemplate jmsTemplate;
}

这似乎是错误和复杂的。问题是减少此配置并将主机作为参数传递。换句话说,我想告诉 Spring:“创建 jmsTemplate 并将 connectionFactory 的属性 host 设置为这个值。”

4

2 回答 2

1

您的建议的问题是 JMS 连接器是一个单例,这意味着它在您的应用程序中的所有对象/线程之间共享。因此,在一个对象/线程中更改其主机配置将导致使用它的其他对象/线程出现问题。

我的建议是您使用spring bean“父级”(参见* 1)定义到每个适用主机的不同jms连接,然后使用@Resource而不是autowire(或@Autowire @Qualifier组合来强制bean参见* 2)

编辑:另一种可能的解决方案是使用 FactoryBean(s) 虽然我不是 100% 确定语法。

*1 http://www.mkyong.com/spring/spring-bean-configuration-inheritance/

*2使用注解按名称自动装配spring bean

于 2013-09-23T13:27:00.280 回答
0

这就是我所做的:

我有不同的属性文件,其中包含不同环境的连接信息,如本地、开发和生产。

  • db.local.properties
  • db.dev.properties
  • db.prod.properties

通过设置环境变量运行我的应用程序时,我只使用了其中一个属性文件:

<bean id="dbPlaceholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
   <property name="location" value="classpath:db.${db.environment:dev}.properties"/>
</bean>

在这里你可以看到我使用了一个环境变量,{db.environment}如果该值未定义,则默认为 dev 形成文件名db.dev.properties

我的下一步是在我运行应用程序的不同环境中定义变量

java -Ddb.environenment=prod ...

由于我使用的是 Tomcat,因此我在 中定义了该变量sentenv.sh,但我很确定其他应用程序服务器提供了类似的机制。

然后我的代码使用属性文件提供的参数

@Value("${db.url}")
private String databaseUrl;
@Value("${db.userName}")
private String userName;
@Value("${db.password}")
private String password;
于 2013-09-23T13:14:05.850 回答