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

消息驱动EJB

消息驱动Bean就是一个标准的JMS消息异步消费者

通过使用MDB规范,开发者只需要实现一个onMessage(Message msg)方法,甚至无须获取JMS Session,也无须理会MDB何时启动——EJB容器会自动启动MDB来监听消息目的,开发者只要通过Annotation来指定JMS消息目的、消息目的的类型即可。

为了区分无状态Session BeanMDB的适用场景,只要把握他们的区别即可:无状态的Session Bean提供了业务接口,客户端需要用同步方式来调用无状态Session BeanMDB则不允许客户端直接调用,只是一个消息监听者。

下面是消息驱动EJBBean类的基本要求

1)MDBBean实现类必须直接(通过类声明)或间接(通过Annotation或部署描述文件)来实现消息监听器接口MessageListener

2)MDB类只能是一个使用public修饰的POJO,不能是其他MDB类的子类

3)MDB类必须包含无参数的构造器。如果程序员没有为MDB类提供构造器,系统将会为之提供无参数的构造器

4)由于EJB容器会操作MDB类,因此不要使用finalabstract修饰MDBBean实现类

5)MDB类中不应该定义finalize方法。如需要回收资源,应该利用@PreDestroy修饰的方法来回收。

 

使用@MessageDriven时可以指定一个messageListener属性,该属性指定MDB Bean实现类锁实现的接口,从而可以让MDBBean实现类间接地实现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.Topicjavax.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();
		}
	}
}

将上面的类打包部署在服务器上,即可监听JNDIMessageQueue的消息目的。

在实际中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

你可能感兴趣的:(java,读书笔记,ee)