Message-Driven Bean(MDB)是EJB當中用以處理JMS的Bean,它是受EJB容器所管理的MessageListener,MDB基本上設計為無狀態(Stateless),並可以使用EJB容器的各種資源,例如交易。
以 第
一個 Session Bean(單機客戶端) 為例,來為其加入MDB,在EJB伺服端,您可以新增一個MDB如下:
package onlyfun.caterpillar;
import java.util.logging.Level; import java.util.logging.Logger; import javax.ejb.ActivationConfigProperty; import javax.ejb.MessageDriven; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.TextMessage;
@MessageDriven(mappedName = "jms/HelloQueue", activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") }) public class HelloMessageBean implements MessageListener { public void onMessage(Message message) { try { TextMessage txtMessage = (TextMessage) message; System.out.println(txtMessage.getText() + " processed....Orz"); } catch (JMSException ex) { Logger.getLogger(HelloMessageBean.class.getName()) .log(Level.SEVERE, null, ex); } } }
MDB為受EJB容器所管理的MessageListener,所以實作了
MessageListener介面,在EJB3中,使用@MessageDriven標示它為MDB,而它的JNDI查找名稱為
"jms/HelloQueue",若您使用NetBeans+Glassfish,將這個MDB部署上去後,會自動在Glassfish的資源當中為您
建立ConnectionFactory,JNDI名稱為"jms/HelloQueueFactory",以及建立Destination,JNDI名
稱為"jms/HelloQueue"。
您可以使用@MessageDriven的屬性messageListenerInterface來指定要實作哪個
MessageListener,如此可不用implements來實作MessageListener介面,實作時有個onMessage方法即可,另一個方式是用部署描述檔來指定實作介面,例如:
....
<message-driven>
<ejb-name>HelloMessageBean</ejb-name>
<ejb-class>onlyfun.caterpillar.HelloMessageBean </ejb-class>
<messaging-type>javax.jms.MessageListener</messaging-type>
....
</message-driven>
...
要讓其它的元件或Bean取得MDB,首先要讓它們取得ConnectionFactory以及Destination,在DJB3上,這是由容器所管理,您可以將之注入其它元件或Bean中,例如:
package onlyfun.caterpillar;
import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.Resource; import javax.ejb.Stateless; import javax.jms.*;
@Stateless(name="ejb/HelloFacade", mappedName="ejb/HelloFacade") public class HelloBeanImpl implements HelloBean { @Resource(name="jms/HelloQueueFactory") private ConnectionFactory connectionFactory; @Resource(name="jms/HelloQueue") private Destination queue;
public String doHello(String message) { String result = null; try { result = message + "processed....";
Connection connection = connectionFactory.createConnection(); Session session = connection.createSession( false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(queue); TextMessage textMessage = session.createTextMessage(); textMessage.setText(result); producer.send(textMessage);
producer.close(); session.close(); connection.close(); } catch (JMSException ex) { Logger.getLogger( HelloBeanImpl.class.getName()).log(Level.SEVERE, null, ex); } return result; } }
您使用@Resource標注要注入的資源之JNDI名稱,容器會自動將ConnectionFactory以及Destination注入,接下來就是JMS的處理流程了(參考 簡介 Java Message Service)。
接下來,當您執行 第
一個 Session Bean(單機客戶端) 中的客戶端程式,除了客戶端程式會出現"XD...processed...."的訊息之外,依伺服端的MDB設計,在伺服端的主控台下也會出現"XD processed....Orz"的訊息。
|