将JBoss 5应用程序迁移到JBoss AS 7(7.1.1.FINAL)时,我遇到了一个新的JMS消息驱动EJB问题。在消息处理中,必须检查一些主数据字段。为了提高性能,应使用@Singleton @Startup
EJB将此主数据预加载到缓存结构中,这需要大约30秒来加载数据。
我的问题是即使缓存尚未完全初始化,队列消息处理也会开始,从而导致消息验证错误。
我尝试在MDB和启动EJB之间定义依赖关系,但据我所知,@DependsOn
注释仅适用于@Singleton
EJB。所以很明显我的解决方案不起作用; - )
启动bean代码:
@Singleton
@Startup
public class StartupBean {
@PostConstruct
void atStartup() {
// TODO load master data cache (takes about 30 seconds)
}
@PreDestroy()
void atShutdown() {
// TODO free master data cache
}
}
注意:我从示例中删除了实际代码,以便于阅读: - )
消息驱动的bean代码:
@MessageDriven(name="SampleMessagingBean", activationConfig = {
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
@ActivationConfigProperty(propertyName="destination", propertyValue="jms/SampleQueue"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")
})
@DependsOn("StartupBean")
public class SampleMessagingBean implements MessageListener {
public void onMessage(Message message) {
// TODO validate message using master data cache
}
}
问题:如何在启动bean加载缓存之前暂停消息处理?
任何建议都非常感谢: - )!
答案 0 :(得分:3)
首先我认为在mdb中注入singleton EJB足以延迟消息消耗 但不,有时它会在Singleton-ejb的@PostConstruct完成之前开始消费该消息。所以也添加了一个方法调用,它开始工作
这适用于glassfish,但我没有看到它不应该在jboss上工作的原因
单件的EJB:
@Singleton
@Startup
public class SingletonBean {
private Logger logger = Logger.getLogger(getClass().getName());
private boolean init = false;
public boolean isInit() {
return init;
}
@PostConstruct
public void init() {
logger.error("singleton init start");
//Do something that takes time here
init = true;
logger.error("singleton init end ");
}
}
和mdb:
@MessageDriven(...)
public class SomeMdb implements MessageListener {
private Logger logger = Logger.getLogger(getClass().getName());
@EJB
SingletonBean sb;
@PostConstruct
public void init() {
logger.error("mdb init start");
if (!sb.isInit()) {
logger.error("never happens");
}
logger.error("mdb init complete");
}
public void onMessage(Message message) {
logger.error("onMessage start");
}
}
现在它始终等待SingletonBean在mdb完成init之前完成init(如日志所示)
19:51:51,980 [ad-pool-1; w: 3] ERROR SomeMdb - mdb init start
19:51:52,122 [ad-pool-4848(4)] ERROR SingletonBean - singleton init start
19:51:56,316 [ad-pool-4848(4)] ERROR SingletonBean - singleton init end
19:51:56,317 [ad-pool-1; w: 3] ERROR SomeMdb - mdb init complete
19:51:56,317 [ad-pool-1; w: 3] ERROR SomeMdb - onMessage start