JMS主题通信的正确使用

JMS主题通信的正确使用,jms,java-ee-6,jms-topic,Jms,Java Ee 6,Jms Topic,我想在JavaEE6项目中使用JMS(主题)。我有一个类,它同时充当一个主题的发布者和订阅者。下面的代码显示了类中最重要的部分 public class MessageHandler implements MessageListener { private static TopicConnectionFactory factory; private static Topic topic; private TopicSubscriber subscriber; p

我想在JavaEE6项目中使用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();
        }
    }     
}
我的问题是,这是否是设计这样一个类的好方法。我的想法是为订阅和发布共享一个连接和会话。但我担心这会导致一些开销或阻塞,因为在不再需要对象之前,我不会关闭连接、会话、订阅者和发布者。我在网上找到的所有示例在发送或接收消息后直接关闭所有内容


提前谢谢

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

无论何时使用消息传递系统,您都可以同时充当这两个角色,但为什么您要为同一主题这样做,您肯定不想接收自己的消息

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

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


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

发布者不会收到他自己的消息,因为我可以使用方法session.createSubscriber(主题、过滤器、noLocal)并将noLocal参数设置为true。摘自javadoc:“在某些情况下,连接可能同时发布和订阅主题。subscriber NoLocal属性允许订阅者禁止传递其自身连接发布的消息。此属性的默认值为false。”此外,此设计最适合我的用例。但事实上,我改变了一件事:在每次sendMessage调用中,都会创建一个发布服务器,并在之后关闭它。我会在我的申请中更改。