简体   繁体   English

Java:MDB和Spring的SingletonBeanFactoryLocator

[英]Java: MDB and Spring's SingletonBeanFactoryLocator

In a code base that I've inherited, there's an MDB which is calling SingletonBeanFactoryLocator().getIntance().useBean() to get a factory reference in its ejbCreate() , and then getting a specific bean from this factory and storing it as an MDB instance variable. 在我继承的代码库中,有一个MDB调用SingletonBeanFactoryLocator().getIntance().useBean()在其ejbCreate()获取工厂引用,然后从该工厂获取特定的bean并将其存储作为MDB实例变量。 (The factory is of type ' ClassPathXmlApplicationContext '). (工厂的类型为“ ClassPathXmlApplicationContext ”)。

The confusing part is: after that bean is obtained, it's calling ' release() ' on this factory reference in that same ejbCreate() . 令人困惑的部分是:在获得该bean之后,它将在该工厂引用的同一ejbCreate()调用' release() '。

Now, this MDB is pooled with poolsize ' x ' and what I've observed is, beans defined in the context xml are getting created ' x ' number of times. 现在,这个MDB是汇集与poolsize“ x ”和我所观察到的是,在定义的bean context xml越来越创建“ x ”的次数。 So my guess is, every time the ' ejbCreate() ' executes, it's creating a context and its beans afresh. 所以我的猜测是,每次执行“ ejbCreate() ”时,它都会创建一个上下文并重新创建其bean。

I checked Spring doc for ' release() above which says: 我在Spring文档中检查了' release()上面的内容:

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

So here're my questions: 所以这是我的问题:

1) is it really creating a new context and new beans everytime ejbCreate() is called? 1) everytime ejbCreate()是否真的创建了一个新的上下文和新的bean?

2) if yes, what happens to the context/beans created in the previous call (eg if the beans are singleton themselves, will they be destroyed )? 2)如果是,在上一次调用中创建的上下文/ bean发生了什么(例如,如果bean本身是单例的,它们将被销毁 )吗?

3) is this the right way to use SingletonBeanFactoryLocator (possibly for thread safety issues) in the context above? 3)在上面的上下文中使用SingletonBeanFactoryLocator (可能是出于线程安全问题)的正确方法吗?

4) if not, what is the right way to use it? 4)如果没有,什么使用它的正确方法?

EDIT: one possibility I can think of is to make the concerned beans prototype to make each MDB instance thread-safe, so there's no need to release and recreate the context. 编辑:我可以想到的一种可能性是使有关的bean prototype使每个MDB实例成为线程安全的,因此无需释放和重新创建上下文。 Awaiting other comments/suggestions. 等待其他意见/建议。

  1. Yes
  2. Nothing happens. 什么都没发生。 The same objects will still be in the same MDBs. 相同的对象仍将位于相同的MDB中。 The MDB doesn't care and Spring is out of the picture at this point. MDB不在乎,Spring目前不在考虑之列。
  3. That really depends on the use circumstances. 这确实取决于使用环境。 If you just use Spring to assemble objects and every MDBs should have it's own instances then the answer is yes. 如果仅使用Spring组装对象,并且每个MDB都应具有其自己的实例,那么答案是肯定的。
  4. Depending on the use case SpringBeanAutowiringInterceptor may or may not be a better alternative. 根据使用情况, SpringBeanAutowiringInterceptor可能是或可能不是更好的选择。
  5. Prototype can be tricky. 原型可能很棘手。 You have to understand your beans and the consequences well to make it do what you expect. 您必须充分了解自己的豆子和后果,才能使其达到您的期望。 That's why it's generally best to make spring beans stateless. 这就是为什么最好使春季豆成为无状态的原因。

Update: There is actually a race condition. 更新:实际上存在比赛条件。 If the container decides to run the ejbCreate() of two MDBs in parallel then they both will end up sharing the same application context. 如果容器决定并行运行两个MDB的ejbCreate() ,则它们最终将共享同一应用程序上下文。

Update 2: I could not find a section that explicitly allows EJB creating through parallel threads but I could also not find a section that explicitly forbids it. 更新2:我找不到明确允许通过并行线程创建EJB的部分,但我也找不到明确禁止通过并行线程创建的部分。

Given the following sections from the spec I assume it would be in the spirit of the spec to do it. 考虑到规范中的以下部分,我认为这样做符合规范的精神。


2.4.2 Message-Driven Objects 2.4.2消息驱动的对象

A typical EJB container provides a scalable runtime environment to execute a large number of mes- sage-driven objects concurrently. 典型的EJB容器提供了可扩展的运行时环境,以同时执行大量消息驱动的对象。

5.2 Goals 5.2目标

A further goal of the message-driven bean model is to allow for the concurrent processing of a stream of messages by means of container-provided pooling of message-driven bean instances. 消息驱动bean模型的另一个目标是允许通过容器提供的消息驱动bean实例池来并发处理消息流。

5.4 Protocol Between a Message-Driven Bean Instance and its Container 5.4消息驱动的Bean实例与其容器之间的协议

It is the container's responsibility to ensure that the message-driven bean comes into existence when the container is started up and that instances of the bean are ready to receive an asynchronous message delivery before the delivery of messages is started. 容器负责确保在启动容器时消息驱动的Bean存在,并且确保Bean的实例准备好在开始传递消息之前接收异步消息传递。

5.4.11 Concurrency of Message Processing 5.4.11消息处理的并发

A container allows many instances of a message-driven bean class to be executing concurrently, thus allowing for the concurrent processing of a stream of messages. 容器允许消息驱动bean类的许多实例同时执行,从而允许并发处理消息流。 No guarantees are made as to the exact order in which messages are delivered to the instances of the message-driven bean class, although the container should attempt to deliver messages in order when it does not impair the concurrency of mes- sage processing. 尽管容器应在不损害消息处理并发性的前提下按顺序发送消息,但是不能保证将消息传递到消息驱动bean类实例的确切顺序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM