我正在尝试通过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>