MDB Tutorial | Mastertheboss

A Message Driven Bean (MDB) is an asynchronous message consumer. The MDB is invoked by the container as a result of the arrival of a message at the destination that is serviced by the MDB. A Message Driven Bean can be used for a single messaging type, in accordance with the message listener interface it employs.
From the client view, a message-driven bean is a message consumer that implements some business logic running on the server. A client accesses the MDB by sending messages to the destination for which the message-driven bean class is the message listener.

Message Driven Bean Goals

  • MDBs are anonymous components. They have no client-visible identity.
  • MDBs have no conversational state. This means that all bean instances are equivalent when they are not involved in servicing a client message.
  • MDBs can be transaction aware
  • A MDB instance has no state for a specific client. However, the instance variables of the message-driven bean instance can contain state across the handling of client messages. Examples of such state, include an open database connection and a reference to an enterprise bean.
    A further goal of the message-driven bean model is to allow for the concurrent processing of a stream of messages by means of container-provided pooling of message-driven bean instances.

A sample Message Driven Bean

import java.util.logging.Logger;
import javax.ejb.*;
import javax.jms.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.annotation.Resource;
import javax.sql.DataSource;

@MessageDriven(name = "MessageMDBSample", activationConfig = {
        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "queue/MyQueue"),
        @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })

public class ExampleMDBean implements MessageListener {

    @Resource
    private MessageDrivenContext context;

    @Resource(lookup="java:jboss/datasources/PostGreDS")
    private DataSource ds;
    
    public void onMessage(Message message) {

         try (Connection con = ds.getConnection();
             PreparedStatement ps = createPreparedStatement(con);
             ResultSet rs = ps.executeQuery()) {

            while(rs.next()) {
                System.out.write("Time from Database: " +rs.getString(1));
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

    }
    private PreparedStatement createPreparedStatement(Connection con) throws SQLException {
        String sql = "SELECT NOW();";
        PreparedStatement ps = con.prepareStatement(sql);
        return ps;
    }
}

This example shows a MDB which will be triggered when a message is sento the the JMS Queue bound in the JNDI tree under the “queue/MyQueue” name.

An MDB client:

We add here a simple Servlet client which sends a batch of messages to the destination where the MDB is actively listening:

@WebServlet("/HelloWorldMDBServletClient") 

public class HelloWorldMDBServletClient extends HttpServlet {
  private static final int MSG_COUNT = 50;
  
  @Inject 
  private JMSContext context;
  @Resource(lookup = "java:/queue/MyQueue") 
  private Queue queue;
  @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.setContentType("text/html");
    PrintWriter out = resp.getWriter();
    try {
      out.write("Sending messages to " + destination);
      out.write("The following messages will be sent to the destination:");
      for (int i = 0; i & lt; MSG_COUNT; i++) {
        String text = "This is message " + (i + 1);
        context.createProducer().send(queue, text);
        out.write("Message (" + i + "): " + text + "");
      }
      out.write("Go to your JBoss EAP server console or server log to see the result of messages processing.");
    } finally {
      if (out != null) {
        out.close();
      }
    }
  }
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    doGet(req, resp);
  }
}

Within this tutorial, we have covered some of the options available to configure an MDB. You can read more about MDB annotations here: 10 Annotations you can use on your MDBs