每个部署的 MDB 都有一个 JMX 管理接口 MBean。此 MBean 的 ObjectName 因部署而异(也可能在 JBoss 版本之间有所不同)。我正在使用 JBoss 4.3,并且 ObjectName 格式是:
Domain Name: jboss.j2ee
service: EJB3
name: <MDB Name>
ear: <EAR Name> (if applicable)
jar: <JAR Name>
如果您的计时器服务是 JBoss ServiceMBean,您可以使用 JBoss @Depends("the timer service ObjectName")批注使 MDB依赖于计时器。这将强制定时器服务在 MDB 启动之前启动(因此最好使定时器服务有一些启动后延迟)但更重要的是,我相信在取消部署时会发生相反的情况,定时器服务应该首先停止,然后是 MDB。
如果可行,它会负责排序,但我认为您不能在计时器运行时强制 MDB 不取消部署。您的应用程序的详细信息可能不支持这一点,但您可能考虑解决此问题的一种方法是使用JBoss Quartz JCA Inflow Adapter,它本质上将定时器和消息处理器绑定到一个(它就像一个 MDB,但它接收定时器事件而不是消息),使您不必为两个组件之间的依赖关系而苦苦挣扎。
================================= 尝试#2 =============== ==================
好的,所以您想防止 MDB 在馈送队列的深度大于零时停止。这种方法应该对您有用,尽管它高度特定于 JBoss。
- 实现一个JMX NotificationListener,它监听 MDB Delegate MBean 的状态变化。
- 您还可以实现JMX NotificationFilter来缩小您想要监听的特定事件的范围。
- 您要查找的状态更改在属性State上,您要查找的转换是3 --> 1 ( Started --> Stopping )
- [此版本] JBoss 中的 JMX 通知是同步发出的,并且会阻塞直到通知侦听器返回。当您的侦听器收到此通知时,在 MDB 的馈送队列 MBean 上启动轮询循环(没有询问您是否使用了 JBoss Messaging,但我假设您是)。当MessageCount > 0 时,您继续轮询。当队列的消息计数为零时,侦听器返回,MDB 将停止。
- 确保在轮询循环中添加一个短暂的睡眠,以及轮询超时(以防事情变得古怪)。
- 您也可以考虑在至少n 个轮询循环的消息计数为 0 之前不返回,以防在传输过程中有一些未提交的消息可能不会显示在消息计数中。
底线是,当您的属性更改侦听器被调用时,消息将继续被处理。当属性更改侦听器返回时,MDB 停止将继续。
如果您的 JMS 实现是本地虚拟机内 JBoss 消息传递,则队列消息计数将在队列的管理 MBean 中可用。对于任何其他设置,您可能需要进行专有的 JMS API 调用来获取队列的消息计数,或者,使用更暴力的方法,您可以简单地请求 JMS QueueBrowser并计算消息的数量。