A MDB (Message-Driven Bean) is a bean used by JMS to listen to new asynchronous messages. In the same way as any other Java EE enterprise bean, the EJB container in which the MDB runs takes care of the bean lifecycle so you do not have to configure a listener by yourself and add all the required boilerplate.
The main difference between regular session beans and MDBs is that clients don’t access message-driven beans through interfaces, instead MDBs are listening to messages published by a JMS application.
MDB Class
MDBs are regular Java classes that implement javax.jms.MessageListener and are annotated with @MessageDriven. The MessageListener requires that you implement the onMessage() method that is invoked when a message arrives, so we can process the message. You will have to cast the message to one of the five JMS message types (BytesMessage, MapMessage, ObjectMessage, StreamMessage, TextMessage).
Messages are delivered in a transaction context, in other words, if for some reason an exception is thrown, the message will be redelivered.
Message-driven bean classes allow you to set configuration properties to specify things like destination name and destination type. You can define a @ActivationConfigProperty as a value of the parameter activationConfig that is accepted by @MessageDriven to set destination and destinationType . i.e.
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destination", propertyValue = "myQueue"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class MyMessageDrivenBean implements MessageListener {
private static final Logger LOGGER = Logger.getLogger(MyMessageDrivenBean.class.getName());
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
LOGGER.info("Message received: " + textMessage.getText());
} catch (JMSException e) {
LOGGER.severe("Something went wrong when consuming message: " + e.getMessage());
}
}
}
The destination type can also be a topic if you specify as the property value
javax.jms.Topic.
Other Configuration Properties
| Property Name | Property Value | Description |
|---|---|---|
acknowledgeMode | AUTO_ACKNOWLEDGE (default) | An acknowledge message is sent automatically |
acknowledgeMode | DUPS_OK_ACKNOWLEDGE | An acknowledgment message is not sent to the client right away. This is good for performance. |
subscriptionDurability | NonDurable (default) | If nobody is listening to the topic the message is missed |
subscriptionDurability | Durable | Ensures that messages sent to a topic are not missed |
Acknowledgment for an MDB is managed by the container, so only the two automatic modes above apply —
CLIENT_ACKNOWLEDGEis not a validacknowledgeModefor a message-driven bean.
Lifecycle Callbacks and Interceptors
MDBs are compatible with enterprise bean lifecycle methods:
@PostConstruct: the method is invoked before the first message is received by the MDB.@PreDestroy: the method is invoked when the MDB is removed from the pool or destroyed.
Interceptors are also allowed. We can define our interceptor as a method annotated with @AroundInvoke. These methods will be invoked before and after the execution of the onMessage() method.
Image by Antonios Ntoumas from Pixabay
