您的位置:首页 > 编程语言 > Java开发

【JavaEE】经典JAVA EE企业应用实战-读书笔记12

2017-02-17 17:36 197 查看
消息驱动EJB
消息驱动Bean就是一个标准的JMS消息异步消费者
通过使用MDB规范,开发者只需要实现一个onMessage(Message msg)方法,甚至无须获取JMS
Session,也无须理会MDB何时启动——EJB容器会自动启动MDB来监听消息目的,开发者只要通过Annotation来指定JMS消息目的、消息目的的类型即可。
为了区分无状态Session Bean和MDB的适用场景,只要把握他们的区别即可:无状态的Session
Bean提供了业务接口,客户端需要用同步方式来调用无状态Session Bean。MDB则不允许客户端直接调用,只是一个消息监听者。
下面是消息驱动EJB的Bean类的基本要求
1)MDB的Bean实现类必须直接(通过类声明)或间接(通过Annotation或部署描述文件)来实现消息监听器接口MessageListener
2)MDB类只能是一个使用public修饰的POJO,不能是其他MDB类的子类
3)MDB类必须包含无参数的构造器。如果程序员没有为MDB类提供构造器,系统将会为之提供无参数的构造器
4)由于EJB容器会操作MDB类,因此不要使用final或abstract修饰MDB的Bean实现类
5)MDB类中不应该定义finalize方法。如需要回收资源,应该利用@PreDestroy修饰的方法来回收。
 
使用@MessageDriven时可以指定一个messageListener属性,该属性指定MDB
Bean实现类锁实现的接口,从而可以让MDB的Bean实现类间接地实现MessageListener接口。
@MessageDriven可以指定如下属性
1)mappedName:指定MDB正在监听的消息主题或消息队列的JNDI名称。
2)name:指定MDB的标识名
3)messageListener:指定MDB Bean类所实现的接口
4)activationConfig:可接受一组@ActivationConfigProperty作为参数,每个@ActivationConfigProperty配置一组key-value对,用于为MDB配置额外的属性,可以指定几个常用的属性如下
1)acknowledgeMode:指定JMS消息的确认方式
2)destinationType:指定MDB所监听消息目的的类型,可以是javax.jms.Topic或javax.jms.Queue两个值的其中之一,分别代表消息主题和消息队列。
3)destination:指定MDB所监听的消息目的的JNDI绑定名
 @MessageDriven(activationConfig = {//
@ActivationConfigProperty(//
propertyName = "destinationType", propertyValue = "javax.jms.Queue"),//
@ActivationConfigProperty(//
propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),//
@ActivationConfigProperty(//
propertyName = "destination", propertyValue = "MessageQueue") }, //
messageListenerInterface = javax.jms.MessageListener.class, //
mappedName = "MessageQueue")
public class SimpleMDB {
public void onMessage(Message msg) {
try {
if (msg instanceof TextMessage) {
TextMessage txt = (TextMessage) msg;
String content = txt.getText();
System.out.println("the message is " + content);
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}
将上面的类打包部署在服务器上,即可监听JNDI为MessageQueue的消息目的。
在实际中MDB获取了JMS消息之后,可以调用容器中其他Session
Bean来处理该消息——只要通过依赖注入将Session Bean注入到该MDB中即可。

也可以实现MessageListener接口,这样可以不用通过@MessageDriven设置间接的实现的接口。
 @EJB(name = "StudentBean")
private Student student;

public void onMessage(Message msg) {
try {
if (msg instanceof TextMessage) {
TextMessage txt = (TextMessage) msg;
String content = txt.getText();
System.out.println("the message is " + content);
student.say(content);
} else if (msg instanceof MapMessage) {
MapMessage map = (MapMessage) msg;
String name = map.getString("name");
int age = map.getInt("age");
System.out.println(name + "\t" + age);
}
} catch (JMSException e) {
e.printStackTrace();
}
}
上面的例子使用@EJB来修饰student,告诉EJB容器应将名为“StudentBean”的EJB注入该Field。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: