我们使用的应用程序包含一个jboss@Service mbean,它封装了一个javax.jms.Connection对象。
在mbean启动期间,通过初始化远程InitialContext、从该上下文查找ConnectionFactory并从该工厂创建连接来创建连接:
@Service
public class JMSPublisher extends etcc.... {
private Connection connection;
protected void startService() {
Context ctx = getRemoteInitialContext();
ConnectionFactory connectionFactory = (ConnectionFactory) ctx.lookup("ConnectionFactory");
connection = connectionFactory.createConnection();
}
}
我的问题是:我们应该保持这种联系多久?在实践中,当我们在未定义的时间后尝试在连接上创建会话时,我们会看到连接抛出JMSException。
Connection的文档告诉我们,对象表示一个套接字,因此由于不活动而导致的超时可能是正常的。但是,如果不为每条消息创建新的连接,我们如何应对呢?
您的最佳选择是让JMSPublisher实现javax.jms.Exception侦听器。实现connect((方法,该方法可以安全地获取上的连接
- startService
- on异常
额外的几点:
-
对于代码压缩,只需通过资源注入获取JMS连接工厂即可。连接工厂引用将在调用startService之前解析,并且还将充当隐式依赖项,使JMS连接工厂成为服务的依赖项。
-
让JMSPublisher扩展org.jbos.system.ServiceMBean支持并实现一个扩展org.jboss.system.ServicesBean的令牌MBean接口(JMSPublish MBean(。这将确保在服务启动(和停止(时遵守依赖关系。
资源注入JMS连接工厂
@Resource(mappedName="ConnectionFactory")
private javax.jms.ConnectionFactory connectionFactory;
private volatile javax.jms.Connection connection;
修改的startService((
public void startService() {
connect();
}
连接异常处理程序
public void onException(JMSException je) {
connect();
}
*安全连接初始化程序(添加conn.start(((*
private void synchronized connect() {
log.info("Initializing Connection....");
try {
if(connection!=null) {
try { connection.stop(); } catch (Exception e) {}
try { connection.close(); } catch (Exception e) {}
}
connection = connectionFactory.createConnection();
connection.setExceptionListener(this);
connection.start();
} catch (Exception e) {
log.error("Failed to intialize JMS connection", e);
}
}
这不会自动处理通过丢失的连接分配的其他JMS资源,但如果其他组件正在使用该组件所拥有的连接,则可以从JMSPublisher发布JMX通知,指示连接已丢失,并在收到通知时清理/重新获取。