使用ActiveMQ和Spring的JMS Standalone消费者

时间:2012-06-08 15:58:57

标签: java spring tomcat activemq

从历史上讲,我已将我的JMS使用者应用程序部署为在Tomcat(Windows框)下部署的Spring Web应用程序。然后,这些消费者将在同一个Tomcat实例下与我的其他Web应用程序一起运行。然而,随着我使用的消费者数量的增长,我意识到这会变成一种维护噩梦。

我的解决方案是将这些webapps转换为部署为jar的“main method”独立应用程序。实际上,我能够成功地将它们打包在一起,以尝试尽可能多地重用资源(DAO,依赖项等)。

这是我的主要方法:

public static void main(String[] args) {

    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    try {
        FooListener fooListener = (FooListener) context.getBean("fooListener");

        fooListener.start();
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    }

    try {
        BarListener barListener = (BarListener) context.getBean("barListener");

        barListener.start();
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
    }
}

我的问题:

  1. 在主方法应用程序中关闭我的JMS连接是否需要执行任何特殊操作,或者在应用程序终止时它们是否会关闭?
  2. 是否有人有任何个人偏好或其他方面是否使用tomcat或作为独立应用部署jms消费者?
  3. 编辑:

    更多信息:FooListener和BarListener扩展了以下抽象类。它们从applicationContext.xml文件中的相应bean继承它们的值,它们都覆盖onMessage()方法以异步使用消息。

    public abstract class TextMessageListener implements MessageListener {
    
        protected ConnectionFactory connectionFactory;
    
        protected String queueName;
    
        protected String selectors;
    
        public void start() throws JMSException {
            Connection connection = connectionFactory.createConnection();
    
            Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
    
            MessageConsumer consumer = session.createConsumer(session.createQueue(queueName), selectors);
    
            consumer.setMessageListener(this);
    
            connection.start();
        }
    
        public abstract void onMessage(Message message);
    }
    

1 个答案:

答案 0 :(得分:4)

您必须以这种方式为您的应用程序上下文注册一个关闭钩子:

context.registerShutdownHook();

这将确保当jvm关闭时,上下文也会正常关闭。

我的个人偏好始终是将其部署到容器 - 甚至是像这样的独立应用程序,这是由于以下原因:

  • 管理更容易 - 部署/取消部署应用程序之战,启动/停止容器运行时。
  • 如果您需要构建任何类型的监控 - 消耗了多少消息,使用此设置将更容易,您可以添加显示相关信息的网页,而不是使用jmx与独立应用程序。

另外,为什么要显式调用listener.start(),Spring容器会自动执行此操作?