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.