【问题标题】:Correct usage of JMS-Topic communicationJMS-Topic通信的正确使用
【发布时间】:2013-03-13 21:35:49
【问题描述】:

我想在我的 JavaEE 6 项目中使用 JMS(主题)。我有一个类可以同时充当主题的发布者和订阅者。以下代码显示了该类中最重要的部分。

public class MessageHandler implements MessageListener {
    private static TopicConnectionFactory factory;
    private static Topic topic;

    private TopicSubscriber subscriber;
    private TopicPublisher publisher;

    public MessageHandler() throws NamingException, JMSException {
            if (factory == null) {
                Context context = new InitialContext();
                factory = (TopicConnectionFactory) new InitialContext()
                        .lookup("jms/myfactory");
                topic = (Topic) context.lookup("jms/mytopic");
            }
            TopicConnection connection = factory.createTopicConnection();
            connection.start();
            TopicSession session = connection
                    .createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
            subscriber = session.createSubscriber(topic);
        }

    @Override
    public void onMessage(Message message) {
        try {
            ObjectMessage msg = (ObjectMessage) message;
            Object someO=  msg.getObject();
            System.out.println(this + " receives "+someO);
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }

    public void sendMessage(Object someO) {
        try {
            ObjectMessage msg = session.createObjectMessage();
            msg.setObject(someO);
            publisher = session.createPublisher(topic);
         publisher.publish(msg);
         publisher.close();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }     
}

我的问题是,如果这是设计这样一个类的好方法。我的想法是为订阅和发布共享一个连接和会话。但我担心这可能会导致一些开销或阻塞,因为我不会关闭连接、会话、订阅者和发布者,直到不再需要该对象。我在网上找到的所有示例都在发送或接收消息后直接关闭所有内容...

提前致谢!

【问题讨论】:

    标签: jms java-ee-6 jms-topic


    【解决方案1】:

    为什么您希望该类同时成为订阅者和发布者?

    无论何时使用消息系统,您都可以同时充当两者,但为什么要针对同一个主题这样做,您肯定不想收到自己的消息?

    因此,主题的目的是在应用程序内的多个部分或多个应用程序之间使用 - 一个是将消息放入主题中,而其他人则接收他们订阅的消息。

    这也解释了您在示例中看到的内容 - 消息处理是一次性的,因此可以在之后关闭连接。

    顺便说一句,既然您在“java-ee 6”领域提出这个问题 - 您不能使用消息驱动 bean、注释您的主题配置并让应用程序服务器为您完成基础架构部分吗?

    【讨论】:

    • 发布者不会收到他自己的消息,因为我可以使用方法 session.createSubscriber(topic,filter,noLocal) 并将 noLocal 参数设置为 true。 javadoc 的摘录:“在某些情况下,一个连接可能同时发布和订阅一个主题。订阅者 NoLocal 属性允许订阅者禁止传递其自己的连接发布的消息。此属性的默认值为 false。”这种设计也最适合我的用例。但实际上我改变了一件事:在每次 sendMessage 调用时,都会创建一个发布者并在之后关闭。
    • 你是对的消息驱动bean。我将在我的应用程序中更改它。
    猜你喜欢
    • 2015-09-07
    • 2019-10-16
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    • 2010-12-08
    • 2018-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多