Recently there was a long TSS thread on Message Driven POJO and arguments were made for and against Message Driven Bean. I thought it will be beneficial for many readers if I blog how MDB has been simplified in EJB 3.0.
In EJB 2.1, MDB was the only beast that was simple for developers to comprehend.
However it required implementation of javax.ejb.MessageDriven interface and its message listener interface.
It also required configuration in multiple XML files e.g. standard deployment descriptor (ejb-jar.xml) and vendor specific deployment descriptors e.g. orion-ejb-jar.xml. EJB3 further simplified MDB and MDB is now a POJO and no longer requires implementation of MessageDriven interface.
Here is an example of a typical MDB in EJB3 that listens to the default message provider.
@MessageDriven( activationConfig = { @ActivationConfigProperty(propertyName="connectionFactoryJndiName", propertyValue="jms/TopicConnectionFactory"), @ActivationConfigProperty(propertyName="destinationName", propertyValue="jms/demoTopic"), @ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Topic"), @ActivationConfigProperty(propertyName="messageSelector", propertyValue="RECIPIENT = 'MDB'") } ) public class MessageLogger implements TimedObject { @Resource javax.ejb.MessageDrivenContext mc; public void onMessage(Message message) { System.out.println("onMessage() - " + message); try { String subject = message.getStringProperty("subject"); String inmessage = message.getStringProperty("message"); System.out.println("Message received\n\tDate: " + new java.util.Date() + "\n\tSubject: " + subject + "\n\tMessage: " + inmessage + "\n"); System.out.println("Creating Timer a single event timer"); TimerService ts = mc.getTimerService(); // Created a single event timer that expires after 30 secs Timer timer = ts.createTimer(30000, subject); System.out.println("Timer created by MDB at: " + new Date(System.currentTimeMillis()) +" with info: "+subject); } catch (Throwable ex) { ex.printStackTrace(); } } public void ejbTimeout(Timer timer) { //Implement Your Business Logic Here } }
If you look carefully the MDB does not implement the javax.jms.MessageListener interface because I'm using the MDB to listen to a JMS provider.
However you can specify the message listener interface by specifying messageListenerInterface. For example, you have an MDB that implements abc.mail.EmailListener then you can specify messageListenerInterface= abc.mail.EmailListener as an attribute for the MessageDriven annotation.
The JMS destination information is provided using annotations. You no longer have to use XML descriptor unless you love descriptors. However descriptors are not irrelevant and you can use descriptors to override the settings in the annotations.
It is worth mentioning here that, EJB 3.0 also simplifies the use of JMS objects by using dependency injection. So if you want to use send a message to the message destination used by the MDB in our example from another EJB, you can use the following code instead of the complex JNDI code required in EJB 2.1
@Resource(name="jms/demoTopic") private javax.jms.Topic demoTopic; @Resource(name="jms/TopicConnectionFactory") private javax.jms.TopicConnectionFactory topicConnectionFactory; TopicConnection connection= topicConnectionFactory.createTopicConnection(); I think these simplifications will make life simpler for developers.
You can download example code for this MDB and EJB3 preview container and see more EJB 3.0 examples from http://otn.oracle.com/ejb3/
6:13:41 AM
|