Message-Driven Bean(MDB)是EJB當中用以處理JMS的Bean,它是受EJB容器所管理的MessageListener,MDB基本上設計為無狀態(Stateless),並可以使用EJB容器的各種資源,例如交易。
以 第 一個 Session Bean(單機客戶端) 為例,來為其加入MDB,在EJB伺服端,您可以新增一個MDB如下:
- HelloMessageBean.java
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>
...
      
      
      <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中,例如:
- HelloBeanImpl.java
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"的訊息。

