Module 11 Developing Message-Driven Beans Objectives Describe the properties and life cycle of message-driven beans Create a JMS message-driven bean Create lifecycle event handlers for a JMS message-driven bean 303 Ω Omega Ω 1
Introducing Message-Driven Beans Message-driven beans are intended as an asynchronous message consumer. Message-driven beans implement a message listener interface: For example, JMS message-driven beans implement the JMS API MessageListener interface. The bean designer is responsible for the message listener method code. The deployer supplies information for the container to register the message-driven bean as a message listener with the destination. 304 Ω Omega Ω Java EE Technology Client View of Message-Driven Beans Containers can create and pool multiple instances of messagedriven beans to service the same message destination. 305 Ω Omega Ω 2
Life Cycle of a Message-Driven Bean 306 Ω Omega Ω Types of Message-Driven Beans JMS message-driven beans: Are annotated with @javax.ejb.messagedriven and implement the javax.jms.messagelistener interface. Application server can integrate support or use connector. Non JMS message-driven beans: Are annotated with @javax.ejb.messagedriven and implement a message listener interface specific to the messaging service. Application server requires a connector. 307 Ω Omega Ω 3
Creating a JMS Message-Driven Bean 1. Declare the message-driven bean class: Class must be public but not final or abstract. 2. Annotate the message-driven bean class using the MessageDriven metadata annotation Specify values with the following attributes: activationconfig = { @ActivationConfigProperty(propertyName = "acknowledgemode, propertyvalue = "Auto-acknowledge ), @ActivationConfigProperty(propertyName = "destinationtype, propertyvalue = "javax.jms.queue") 308 Ω Omega Ω Creating a JMS Message-Driven Bean 3. Optionally, use resource injection to get a MessageDrivenContext instance. 4. Include a public no-argument empty constructor. 5. Write the onmessage method of the MessageListener interface. 6. Do not define a finalize method. 309 Ω Omega Ω 4
Message-Driven Bean Class Simple Example import javax.ejb.*; import javax.jms.*; @MessageDriven(mappedName = "jms/myqueue",activationconfig = { @ActivationConfigProperty(propertyName= "acknowledgemode", propertyvalue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationtype", propertyvalue = "javax.jms.queue") ) public class SampleMDB implements MessageListener { public void onmessage(message message) { 310 Ω Omega Ω Coding the Message-Driven Bean Class import javax.ejb.*; import javax.annotation.*; import javax.naming.*; import javax.jms.*; /** * The MessageBean class is a JMS message-driven bean. It * indirectly implements javax.jms.messagelistener interface. * It is defined as public (but not final or abstract). * It defines a constructor and the onmessage method. */ @MessageDriven { mappedname="destinationtype", messagelistenerinterface = javax.jms.messagelistener, activationconfig = { @ActivationConfigProperty(propertyName="messageSelector", propertyvalue="recipient = MDB ") 311 Ω Omega Ω 5
Coding the Message-Driven Bean Class import javax.ejb.*; import javax.annotation.*; import javax.naming.*; import javax.jms.*; /** * The MessageBean class is a JMS message-driven bean. It * indirectly implements javax.jms.messagelistener interface. * It is defined as public (but not final or abstract). * It defines a constructor and the onmessage method. */ @MessageDriven { mappedname="destinationtype", messagelistenerinterface = javax.jms.messagelistener, activationconfig = { @ActivationConfigProperty(propertyName="messageSelector", propertyvalue="recipient = MDB ") 312 Ω Omega Ω Coding the Message-Driven Bean Class public class MessageBean { @Resource private MessageDrivenContext mdc = null; // Constructor, which is public and takes no arguments. public MessageBean() { System.out.println( In MessageBean.MessageBean() ); // onmessage method, public not final or static // Casts the incoming Message to a TextMessage and displays // the text. public void onmessage(message inmessage) { TextMessage msg = null; try { if (inmessage instanceof TextMessage) { msg = (TextMessage) inmessage; 313 Ω Omega Ω 6
Coding the Message-Driven Bean Class System.out.println( MESSAGE BEAN: Message + received: + msg.gettext()); else { System.out.println( Message of wrong type: + inmessage.getclass().getname()); catch (JMSException e) { System.err.println( MessageBean.onMessage: + JMSException: + e); mdc.setrollbackonly(); catch (Throwable te) { System.err.println( MessageBean.onMessage: + Exception: + te); 314 Ω Omega Ω Complex Message-Driven Bean Classes Using message header message selectors @MessageDriven( activationconfig={ @ActivationConfigProperty( propertyname= messageselector, propertyvalue= JMSType= car AND color= blue AND weight>2500 ) ) Specifying message acknowledgement @MessageDriven( activationconfig={ @ActivationConfigProperty( propertyname= acknowledgemode, propertyvalue= Dups-ok-acknowledge ) ) 315 Ω Omega Ω 7
Callback Methods in a Bean Class import javax.ejb.*; import javax.jms.*; import javax.annotation.*; @MessageDriven public class MessageBean implements MessageListener { @Resource private MessageDrivenContext mdc; public MessageBean() { // constructor @PostConstruct void obtainresources() { @PreDestroy void releaseresources() { public void onmessage(message inmessage) { 316 Ω Omega Ω 8