首页 > 编程 > Java > 正文

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

2019-11-08 03:10:27
字体:
来源:转载
供稿:网友

消息驱动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。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表