Spring JMS消息侦听器中的零星自动连接

时间:2014-09-04 13:24:52

标签: java spring jms message-queue spring-jms

我正在尝试通过Spring Batch实现一个启动作业的队列。队列获取作业消息。处理内容并启动作业。一切都按预期工作了大约50%的时间,我不知道为什么。

以下是一些代码:

public class Listener implements MessageListener {
private static final Logger log = LoggerFactory.getLogger(Listener.class);


@Resource(name = "job")
Job job;

@Resource
JobLauncher jobLauncher;
/**
 * Method called when message is sent to Queue. Reads messages in FIFO
 * @param message Message pulled from Queue
 */
@Override
public void onMessage(Message message) {

    log.info("Message received");
    try {
        String jobName = message.getJMSCorrelationID();

        if (jobName.equals("job")) {
            launchJob(message);
        }
    } catch (JMSException e) {
        log.error("Error with queued message: " + message.toString());
    }

似乎正在发生的事情是,有时@资源不会被初始化。如果我调试,我注意到它们大约有一半时间为空,另一半时间它们是适当连接的。正确的扫描编码到上下文xml文件中。

以下是队列的配置:

<!--  Embedded ActiveMQ Broker -->
<amq:broker id="broker" useJmx="false" persistent="false" >
    <amq:transportConnectors>
        <amq:transportConnector uri="tcp://localhost:0" />
    </amq:transportConnectors>
</amq:broker>

<!--  ActiveMQ Destination  -->
<amq:queue id="destination" physicalName="org" />

<!-- JMS ConnectionFactory to use, configuring the embedded broker using XML -->
<amq:connectionFactory id="jmsFactory" brokerURL="vm://localhost" />

<!-- JMS Producer Configuration -->
<bean id="jmsProducerConnectionFactory"
      class="org.springframework.jms.connection.SingleConnectionFactory"
      depends-on="broker"
      p:targetConnectionFactory-ref="jmsFactory" />

<bean id="localQueueTemplate" class="org.springframework.jms.core.JmsTemplate"
      p:connectionFactory-ref="jmsProducerConnectionFactory"
      p:defaultDestination-ref="destination" />

<!--JMS Consumer Configuration-->
<bean id="jmsConsumerConnectionFactory"
      class="org.springframework.jms.connection.SingleConnectionFactory"
      depends-on="broker"
      p:targetConnectionFactory-ref="jmsFactory" />

<jms:listener-container container-type="default"
                        connection-factory="jmsConsumerConnectionFactory"
                        acknowledge="auto"
                        >
    <jms:listener destination="org" ref="Queue" />
</jms:listener-container>

<bean id="Queue" class="org.Listener" />

我发现其他人可能就是这样了。显然,由于Listeners bean与标准Spring Bean的上下文生活方式不同,因此在监听器中创建bean存在问题。见here。然而,并没有真正的解决方案。并且唯一的解决方案建议我似乎无法使用jms:namespace实现。

编辑:

我已经移动了一些配置上下文。我已将Listener移动到自己的上下文文件中。现在,@ Resource已初始化一次。发送的第一条消息将正确运行作业。每个后续消息似乎都有空启动器和作业。

编辑2:

我已将队列配置移到公共外部的上下文文件中。这似乎解决了这个问题。

基于调试器,似乎正在实例化监听器的多个实例。有些是正确接线而有些则没有。这似乎与实例化实例的顺序有关。移动上下文很可能意味着在创建监听器时bean可用。

因此,似乎我只需要为Queue bean添加一个依赖项,以便它“依赖”作业和作业启动器。我会给这一点,并希望报告回来。

编辑3:

似乎“依赖”不能按预期工作。我选择了将队列逻辑移动到不同配置上下文的解决方案。此上下文导入作业的所有资源。实例化的每个对象(由于某种原因有两个)都是正确连线的。

编辑4:

问题是由上下文文件的多次加载引起的。例如,这是位于web.xml文件中的问题

    <servlet>
      <servlet-name>Job1 Controller</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>controller-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Job1 Controller</servlet-name>
    <url-pattern>/Job1/</url-pattern>
  </servlet-mapping>
  <servlet>
    <servlet-name>Job2 Controller</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>controller-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Job2 Controller</servlet-name>
    <url-pattern>/Job2/</url-pattern>
  </servlet-mapping>

0 个答案:

没有答案