一、概述
消息驱动 bean是一个异步消息消费者。当消息到达消息驱动bean服务的目的地或终端时,容器调用消息驱动bean。消息驱动bean实例是消息驱动 bean类的实例。消息驱动 bean 是为单个消息类型定义的,与它雇用的消息监听器接口一致。
对于客户端,消息驱动 bean 是一个实现了一些业务逻辑运行在服务器上的消息消费者。客户端通过将消息发送到消息驱动 bean 作为消息监听器的目的地或终端来访问消息驱动 bean。
消息驱动 bean是匿名的。它们没有客户端可见的标识。
消息驱动 bean实例没有会话状态。这意味着所有的 bean实例在服务于客户端消息时都是相等的。
消息驱动 bean 实例由容器创建,它用于处理消息。它的生存时间由容器控制。
消息驱动bean 实例对特定客户端来说没有状态。但是,消息驱动bean 实例的实例变量可以在客户端消息处理的整个过程中保持状态。例如,这种状态是数据库连接和对企业bean 的引用。
原文:
A message-drivenbean is an asynchronous message consumer. A message-driven bean is invoked by thecontainer as a result of the arrival of a message at the destination orendpoint that is serviced by the message-driven bean. A message-driven beaninstance is an instance of a message-driven bean class. A message-driven beanis defined for a single messaging type, in accordance with the messagelistenerinterface it employs.
To a client, amessage-driven bean is a message consumer that implements some business logicrunning on the server. A client accesses a message-driven bean by sendingmessages to the destination or end-point for which the message-driven beanclass is the message listener.
Message-drivenbeans are anonymous. They have no client-visible identity.
Message-drivenbean instances have no conversational state. This means that all bean instancesare equivalent when they are not involved in servicing a client message.
A message-drivenbean instance is created by the container to handle the processing of themessages for which the message-driven bean is the consumer. Its lifetime iscontrolled by the container.
A message-drivenbean instance has no state for a specific client. However, the instancevariables of the message-driven bean instance can contain state across thehandling of client messages. Examples of such state include an open databaseconnection and a reference to an enterprise bean.
二、消息驱动 bean实例和容器间的协议
从消息驱动 bean 实例的创建到销毁,它都生存在容器中。容器为消息驱动bean 提供安全、并发、事务和其它服务。容器管理消息驱动 bean 实例的生命周期,当调用bean时通知实例并提供全方位的服务来保证消息驱动bean的实现是规模化的,且能支持大量消息的并发处理。
从 bean提供者的视角来看,消息驱动bean与容器具有相同的生存时间。当容器启动时保证消息驱动bean存在并在消息转发开始前准备好bean实例来接收异步消息都是容器的责任。
容器本身对消息驱动bean实例没有服务要求。容器调用bean实例是为了让实例获取容器的服务和转发容器产生的通知。
由于所有的消息驱动 bean 实例都是相等的,因此客户端消息可以被转发给任何一个实例。
原文:
Protocol Betweena Message-Driven Bean Instance and its Container
From itscreation until destruction, a message-driven bean instance lives in acontainer. The container provides security, concurrency, transactions, andother services for the message-driven bean. The con-tainer manages the lifecycle of the message-driven bean instances, notifying the instances when bean actionmay be necessary, and providing a full range of services to ensure that themessage-driven bean implementation is scalable and can support the concurrentprocessing of a large number of messages.
From the BeanProvider’s point of view, a message-driven bean exists as long as its containerdoes. It is the container’s responsibility to ensure that the message-drivenbean comes into existence when the container is started up and that instances ofthe bean are ready to receive an asynchronous message delivery before thedelivery of messages is started.
Containersthemselves make no actual service demands on the message-driven bean instances.The calls a container makes on a bean instance provide it with access tocontainer services and deliver notifica-tions issued by the container.
Since allinstances of a message-driven bean are equivalent, a client message can bedelivered to any available instance.
三、消息驱动 bean方法的事务上下文
Bean的消息监听器和超时回调方法的事务范围由bean的元数据注释符或部署文件指定的事务属性决定。如果指定 bean 使用容器管理的事务分割,那么必须为消息监听器方法使用 REQUIRED 或 NOT_SUPPORTED 事务属性,为超时回调方法是用 REQUIRED、REQUIRES_NEW 或 NOT_SUPPORTED 事务属性。
当消息驱动 bean 使用 bean 管理的事务分割,用javax.transaction.UserTransaction接口来分割事务时,产生bean 调用的消息接收不是事务的一部分。如果消息接收是事务的一部分,必须使用事务属性是REQUIRED的容器管理事务分割。
newInstance 方法,setMessageDrivenContext,消息驱动 bean 的依赖注入方法,以及生命周期回调方法都在未指定的事务上下文中调用。
四、异常处理
消息驱动 bean的消息监听器方法不能抛出java.rmi.RemoteException。
消息驱动 bean通常不应当抛出RuntimeException。
从消息驱动 bean 类的任何方法(包括消息监听器方法和由容器调用的回调方法)中抛出的 RuntimeException 会引起 bean 的状态转变成“不存在”状态。
如果消息驱动 bean 使用 bean 管理事务分割并抛出 RuntimeException,那么容器不应当确认消息。当多个这种方法应用到 bean类上时应用到生命周期回调拦截器方法的规则。
从客户端视角来看,消息消费者仍继续存在。如果客户端继续向与 bean 关联的目的地或终端发送消息,那么容器可以将消息代理给另一个实例。
某些消息类型的消息监听器方法可以抛出应用异常。应用异常被容器传递到资源适配器。