Chapter 23 906 The second advantage is that a message-driven bean has the ability to process messages concurrently. Though just one message-driven bean acts as a message listener on a JMS destination, the container can manage a pool containing multiple instances of the bean. Each bean instance can consume messages addressed to the message-driven bean. Since message-driven beans can consume messages concurrently they are more scalable than ordinary JMS consumers, which consume messages serially. One drawback of concurrent message consumption is that there is no guarantee that the message-driven bean will process messages in the order in which they are sent. The developer can use APIs to ensure synchronous receipt of messages but this is not a good idea because if a bean is waiting for a message it is in an active state, tying up resources, which reduces scalability. The third advantage is that message-driven beans are easier to develop than ordinary JMS consumers are. The container takes care of a lot of details for the programmer. For example a message-driven bean developer does not need to write the code to create a connection and session. The container manages these objects. One drawback of message-driven beans when compared to normal JMS consumers is that message- driven beans may only listen on one destination, either a single topic or queue. If a developer wishes to have a consumer that listens on multiple destinations they must use a standard JMS consumer or deploy multiple message-driven bean classes. Lifecycle of a Message-Driven Bean The container entirely controls the lifecycle of the message-driven bean. The container creates a message-driven bean to handle messages for which it is the consumer. Unlike entity beans and session beans a message-driven bean has no home or remote interface. A message-driven bean instance is born when the container invokes newInstance() on the message-driven bean class. After the call to newInstance() the container calls setMessageDrivenContext() followed by ejbCreate() on the instance. The message-driven bean instance is now in the ready state, available to receive and process messages sent to its destination (its topic or queue): ejbRemove() Non-Existence Ready State onMessage() 1. newInstance() 2. setMessageDrivenContext() 3. ejbCreate() While the bean instance is in the ready state, the container will call the bean instance's onMessage() method when a message is sent to its destination. When the container no longer needs the instance of the message-driven bean it invokes the bean's ejbRemove() method. Most likely the container will not remove a message-driven bean unless the container is running out of resources or shutting down. Like a stateless session bean, a message-driven bean instance has no internal state, but it can maintain instance variables throughout its life.