在无状态EJB中缓存MessageProducer和/或jms会话

时间:2013-06-06 17:01:52

标签: java java-ee jms

我们在网络上遇到延迟问题。 我对每个连接,会话和生成器创建都有1ms的惩罚。 这就是为什么我想在我的无状态EJB实例变量中缓存我的jms连接,会话和MessageProducer。

我可以在@PostConstruct中创建它们,这样做是否安全?

@Stateless
public class MyEJB {
    @Resource(mappedName = Messaging.LOCAL_JNDI_CONN_FACTORY)
    private ConnectionFactory connectionFactory;

    @Resource(mappedName = AutoRecolteIndexerConsumer.QUEUE_NAME)
    private Queue queue;

    private Connection connection;
    private Session session;
    private MessageProducer producer;


    @PostConstruct
    public void init() {
        connection = connectionFactory.createConnection();// 1ms
        session = connection.createSession(true, Session.SESSION_TRANSACTED);// 1ms
        producer = session.createProducer(queue); //1ms
    }

    public void send(Object data) {
        ObjectMessage obj = session.createObjectMessage();
        obj.setObject(data);
        producer.send(obj);
    }

}

1 个答案:

答案 0 :(得分:2)

预先初始化重量级对象(如连接工厂,连接和会话)没有任何问题,事实上,这是一种很好的做法,因为我们不希望每次发送消息时都创建这些内容。

但我认为你混淆了无状态和有状态的EJB。你正在初始化bean的状态,所以它不是无状态的,它是有状态的。其次,由于你有状态,你的代码应该假设最坏的情况,并在发生错误时清理资源,就像这样......

   public void send(Object data) {
        ObjectMessage obj = session.createObjectMessage();
        obj.setObject(data);
        try{
           producer.send(obj);

        }catch( JMSException jex){
          producer.close();
          session.close();
          connection.close();
          throw new EJBException( jex);
        }
    }

通过清理避免资源泄漏,然后抛出EJBException,以便容器销毁EJB实例并在其位置创建一个新实例。