EJB——消息和消息驱动bean(一)

       与会话bean直接处理来自于客户端的请求一样,MDB直接处理消息。消息有很多用处,包括系统集成、异步处理和分布式系统。Java EE通过再消息发送者和接收者之间添加可靠的中间者使消息健壮。在Java EE的角度来说,可靠的中间者被称为消息目的地(destination),由面向消息的中间件(Message-Oriented Middleware,MOM)管理。Java EE通过众所周知的API——Java消息服务(Java Messaging Service,JMS)标准化信息,MDB在很大程度上依靠它。
    举例说明,网购订单的处理,PlaceOrderBean通过confirmOrder方法生成消息请求并行开始订单账单处理,从而完成异步订单账单处理。此账单处理请求消息一旦发送给消息中间者,confirmOrder就把订单确认信息返回给用户。如下代码,账单处理请求消息发送到名为jms/OrderBillingQueue的消息目的地。
   
   
package com.ejb3inaction.actionbazaar.buslogic;
···
import javax.annotation.Resource;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.jms.*;
···
 
@Stateful
public class PlaceOrderBean implements PlaceOrder {
//注入JMS资源
@Resource(name = "jms/QueueConnectionFactory", mappedName = "ConnectionFactory")
private QueueConnectionFactory connectionFactory;
 
@Resource(name = "jms/OrderBillingQueue", mappedName = "jms/OrderBillingQueue")
private Queue billingQueue;
···
@Remove
public Long confirmOrder() {
Order order = new Order();
order.setBidderId(bidderId);
order.setItems(items);
order.setShippingInfo(shippingInfo);
order.setBillingInfo(billingInfo);
saveOrder(order);
billOrder(order);
return order.getOrderId();
}
···
private void billOrder(Order order) {
try {
//包含JMS设置代码
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(billingQueue);
//创建和发送消息
ObjectMessage message = session.createObjectMessage();
message.setObject(order);
producer.send(message);
//释放JMS资源
producer.close();
session.close();
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
 
}
}
       代码中发送消息的代码在很大程度上依靠JMS API。两个JMS资源,包括消息目的地,是使用@Resource注解注入的,而非通过查找。在EJB 3中,除@EJB注解之外,@Resource注解也提供依赖注入功能。@EJB注解限于注入EJB,而@Resource更通用,可以注入容器的任何内容。
    容器通过name参数找到JMS资源,将其注入到connectionFactory和billingQueue两个实例变量中。name参数的值指定了绑定到EJB环境命名上下文的资源。MessageProducer.send方法不等待接收者在另一端接收消息,因为消息服务器确保消息会传输到对消息感兴趣的任何位置。这样就允许账单处理和订单处理并行开始,消息一旦发送,处理就继续下去。订单和账单处理是松耦合的,订单bean甚至不知道谁将获得并处理它的消息,它只知道消息目的地,最后PlaceOrderBean清理它所使用的所有资源。OrderBillingMDB处理订单账单的请求,持续监听发送到jms/OrderBillingQueue消息目的地的消息,从队列得到消息,检查消息中的order对象,计算用户的账单,下图描述了这一关系。


       使用MDB异步订单账单处理,有状态会话bean向订单账单处理队列发送消息,账单处理MDB得到消息并异步处理。
下面代码实现OrderBillingMDB:
    
    
package ejb3inaction.example.buslogic;
 
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
//是POJO成为MDB
@MessageDriven(activationConfig = {
//指定获取消息的JMS目的地
@ActivationConfigProperty(propertyName="destinationName", propertyValue="OrderBillingQueue"),
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue")
},mappedName = "OrderBillingQueue"
)
public class OrderBillingMDB implements MessageListener {
public void onMessage(Message message) {
try {
 
ObjectMessage objectMessage = (ObjectMessage) message;
Order order = (Order) objectMessage.getObject();
 
try {
bill(order);
notifyBillingSuccess(order);
order.setStatus(OrderStatus.COMPLETE);
} catch (BillingException be) {
notifyBillingFailure(be, order);
order.setStatus(OrderStatus.BILLING_FAILED);
} finally {
update(order);
}
} catch (Exception e) {
e.printStackTrace();
}
 
}
       其实,JMS下的MDB就是会话bean。和无状态bean一样,MDB不确保维护状态。@MessageDriven是MDB的@Stateless注解和@Stateful注解的对应注解,它使容器透明的为POJO提供消息和其他EJB服务。在@ MessageDriven注解内的激活配置属性将通知容器MDB希望从哪一个JMS目的地接收消息。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值