【问题标题】:Suspend MDB message processing until @StartupBean has finished initialization暂停 MDB 消息处理,直到 @StartupBean 完成初始化
【发布时间】:2012-10-30 15:24:47
【问题描述】:

在将 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 完成缓存加载之前暂停消息处理?

任何建议都非常感谢:-)!

【问题讨论】:

    标签: jboss7.x ejb-3.1


    【解决方案1】:

    首先我认为在 mdb 中注入单例 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");
        }
    }    
    

    现在它总是在 mdb 完成 init 之前等待 SingletonBean 完成 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
    

    【讨论】:

      猜你喜欢
      • 2012-01-13
      • 2017-01-13
      • 1970-01-01
      • 1970-01-01
      • 2012-03-25
      • 2010-10-10
      • 1970-01-01
      • 1970-01-01
      • 2019-06-21
      相关资源
      最近更新 更多