Special Edition Using Enterprise JavaBeans 2.0
Prior to the EJB 2.0 Specification, most JMS message consumers were built as simple Java programs that ran outside the container. There was typically a Java program that was started, and that would connect to a JMS destination and listen for incoming messages. Due to the restrictions placed on enterprise beans and non-EJB classes with respect to creating threads, there was no easy way to build an asynchronous JMS consumer inside the container. Although many EJB vendors provided services for startup classes and additional thread management capabilities, this was all proprietary to that vendor. For these reasons, external Java programs were used most often as consumers of JMS messages. Although that approach to building JMS consumers was one of the better solutions for overcoming the synchronicity problem, several other problems are associated with running a Java program outside the container to handle JMS messages. The biggest problem is scalability. If the message load begins to grow, you must start multiple Java client applications outside the container to act as multiple consumers or just rely on the single consumer to process all the incoming messages. This can have the effect of filling up the destination and possibly losing some messages if the load grows too high. Even if you did start multiple consumers, eventually you're going to have a problem with too many client programs running. Trying to manage all these clients is tough. A solution was needed for this problem. A container had to be able to manage the life cycle of multiple JMS consumers. This is the main reason why the message-driven bean was invented. The main goal of message-driven beans is to provide concurrent processing of incoming JMS messages by allowing the container to pool and manage message-driven bean instances. This is similar to how the container handles the other enterprise bean types as well. The container can create instances at startup that are ready to be used, and a smaller number of instances can support a large client load because they can be reused. Some EJB vendors were thinking ahead and had the concept of message-driven beans in their EJB 1.1 implementations . However, the EJB specification didn't describe how they should be implemented until version 2.0. Basically, message-driven beans perform some business logic using JMS messages sent to a particular JMS destination. Although message-driven beans have similarities with the other two types of enterprise beans, there are some very distinct differences. Message-Driven Beans Are Anonymous
The biggest difference between message-driven beans and session or entity beans is that a message-driven bean doesn't have a home or component interface. Therefore, message-driven beans are completely hidden from the client. This is true for standard EJB clients as well as other enterprise beans. The only way for clients to communicate with message-driven beans is by sending messages to a JMS destination. Figure 11.1 shows a client's view of interacting with message-driven beans. Figure 11.1. A client can have no direct interaction with message-driven beans.
As you see in Figure 11.1, a client delivers a JMS message to a destination ( Queue or a Topic ) and the container passes this JMS message to an instance of a message-driven bean that has registered itself as a listener for that particular destination. By using a pool of message-driven bean instances, the container is able to handle incoming messages much more efficiently and increase scalability for JMS operations. Instances of a message-driven bean can be put back into a pool, which is allowed to grow and shrink depending on the needs of the container. Message-Driven Beans Are Stateless
Similar to stateless session beans, message-driven beans are not allowed to contain conversational state. This doesn't mean that they can't have instance variables and have instance state; it just means that they cannot be used to store state information for a particular client. This should be very obvious because a client has no way to make a direct call onto the message-driven bean because it lacks a component interface. By ensuring that all instances of the message-driven bean class are identical, the container is able to manage a smaller number of instances in the pool and still handle a larger load. This is because any free instance can be used to handle any incoming request for a given destination. |