我们的网络出现了延迟问题。我对每个连接、会话和制作人创建都有1毫秒的惩罚。这就是为什么我想在我的无状态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);
}
}
预先初始化像连接工厂、连接和会话这样的重量级对象并没有什么错,事实上,这是一个很好的实践,因为我们不想每次发送消息时都创建这些东西。
但是我认为你混淆了无状态和有状态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);
}
}
通过清理来避免资源泄漏,然后抛出ejbeexception,以便容器销毁EJB实例并在其位置创建一个新实例。