Message-Driven Bean

Ein Message-Driven Bean empfängt Nachrichten (siehe Message) und verarbeitet diese asynchron. Es gibt keine Kommunikationsverbindung zu einem Nutzer wie bei den Session Beans (siehe Session Bean). Ein Message-Driven Bean hat keinen inneren Zustand über die Zeitspanne der Verarbeitung einer empfangenen Nachricht hinweg.

Eine Java Klasse kann durch die Annotation @MessageDriven als Message-Driven Bean markiert werden. Die Annotation legt fest, von welcher Destination das Bean Nachrichten empfängt.

Die Klasse muss das Interface MessageListener und damit eine Methode mit der Signatur void onMessage(Message) implementieren. Diese Methode wird aufgerufen, wenn eine Nachricht empfangen und verarbeitet werden soll.

Vor dem ersten Empfang einer Nachricht beginnt der Lebenszyklus des Beans. Es wird implizit erzeugt, deklarierte Resourcen werden eingefügt (Dependency Injection) und die Methode mit der Annotation @PostConstruct wird aufgerufen.

Wenn der Application Server entscheidet, dass er das Bean nicht mehr benötigt, übergibt er es der Garbage Collection, nachdem er die mit @PreDestroy annotierte Methode aufgerufen hat.

Beispielsweise sieht ein Message-Driven Bean so aus:

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.TextMessage;
//
@MessageDriven(name="MessageCopyBean",
activationConfig={
@ActivationConfigProperty(propertyName="connectionFactoryJndiName", propertyValue="jms/QueueConnectionFactory"),
@ActivationConfigProperty(propertyName="destinationName", propertyValue="<Queue Name>"),
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue")
})
public class MessageCopyBean implements MessageListener
{
    private static final Logger logger = Logger.getLogger("MessageCopyBean");
    //
    @Resource(mappedName="jms/QueueConnectionFactory")
    private QueueConnectionFactory connectionFactory;
    //
    @Resource(mappedName="<Queue Name>")
    private Queue responseQueue;
    //
    private QueueConnection connection;
    //
    @PostConstruct
    public void postConstruct() throws JMSException
    {
        connection = connectionFactory.createQueueConnection();
    }
    //
    @PreDestroy
    public void preDestroy() throws JMSException
    {
        connection.close();
    }
    //
    public void onMessage(Message inMessage)
    {
        try
        {
            TextMessage inTextMessage = (TextMessage) inMessage;
            QueueSession session = connection.createQueueSession(true, 0);
            //
            try
            {
                QueueSender sender = session.createSender(responseQueue);
                TextMessage outMessage = session.createTextMessage();
                outMessage.setText(inTextMessage.getText());
                sender.send(outMessage);
                // ohne commit wird von der Oracle SOA Suite 10.1.3.4
                // und auch von JBoss
                // keine Nachricht gesendet
                session.commit();
                logger.info("copies message " + inMessage);
            }
            finally
            {
                session.close();
            }
        }
        catch (JMSException e)
        {
            logger.log(Level.SEVERE, "cannot copy message", e);
        }
    }
}