Java:MDB和Spring的SingletonBeanFactoryLocator

时间:2012-08-03 08:05:39

标签: java spring ejb

在我继承的代码库中,有一个MDB调用SingletonBeanFactoryLocator().getIntance().useBean()来获取ejbCreate()中的工厂引用,然后从这个工厂获取一个特定的bean并将其存储为MDB实例变量。 (工厂的类型为“ClassPathXmlApplicationContext”)。

令人困惑的部分是:在获得该bean之后,它在同一个release()的此工厂引用上调用“ejbCreate()”。

现在,这个MDB汇集了poolize'x',我观察到的是,context xml中定义的bean正在创建'x'号码时间。所以我的猜测是,每次'ejbCreate()'执行时,它都会重新创建一个上下文及其bean。

我查看了Spring文档上面的release(),其中说:

In an EJB usage scenario this would normally be called from `ejbRemove()` and `ejbPassivate()`.

所以这是我的问题:

1)它是否真的创建了一个新的上下文并调用了新的bean everytime ejbCreate()

2)如果是,那么在前一次调用中创建的上下文/ bean会发生什么情况(例如,如果bean本身是单例,那么它们会被销毁)吗?

3)这是在上面的上下文中使用SingletonBeanFactoryLocator(可能是线程安全问题)的正确方法吗?

4)如果没有,使用它的正确方法?

编辑:我能想到的一种可能性是使相关的bean prototype使每个MDB实例都是线程安全的,因此不需要释放和重新创建上下文。等待其他意见/建议。

1 个答案:

答案 0 :(得分:1)

  1. 什么都没发生。相同的对象仍将位于相同的MDB中。 MDB并不关心,此时Spring还不在其中。
  2. 这实际上取决于使用情况。如果您只是使用Spring来组装对象,并且每个MDB都应该拥有它自己的实例,那么答案是肯定的。
  3. 根据用例SpringBeanAutowiringInterceptor可能是也可能不是更好的选择。
  4. 原型可能很棘手。您必须了解您的咖啡豆及其后果,以使其达到预期效果。这就是为什么通常最好使春豆无国籍。
  5. <强>更新 实际上存在竞争条件。如果容器决定并行运行两个MDB的ejbCreate(),那么它们最终将共享相同的应用程序上下文。

    更新2: 我找不到一个明确允许EJB通过并行线程创建的部分,但我也找不到明确禁止它的部分。

    鉴于规范中的以下部分,我认为这样做符合规范的精神。


    2.4.2消息驱动对象

    典型的EJB容器提供可伸缩的运行时环境,以同时执行大量消息驱动的对象。

    5.2目标

    消息驱动bean模型的另一个目标是允许通过容器提供的消息驱动bean实例池来并发处理消息流。

    5.4消息驱动Bean实例与其容器之间的协议

    当容器启动时,容器有责任确保消息驱动的bean存在,并且在启动消息传递之前,bean的实例已准备好接收异步消息传递。

    5.4.11消息处理的并发性

    容器允许消息驱动的bean类的许多实例同时执行,从而允许并发处理消息流。不保证将消息传递到消息驱动bean类的实例的确切顺序,尽管容器应该在不损害消息处理的并发性时尝试按顺序传递消息。