6.2. EJB Component Model OverviewChapter 13 discusses the two fundamental roles in the RMI environment: the client of the remote object and the object itself, which acts as a kind of server or service provider. These two roles exist in the EJB environment as well, but EJB adds a third role, called the container. Figure 6-1 shows a conceptual diagram of how the three EJB roles interact. The container is responsible for interceding between the client (any code that is invoking the EJB) and the EJB component itself. The container also provides all the extra services for an EJB object mentioned earlier: transaction processing, security, object persistence, and resource pooling. If you're familiar with CORBA, you can think of the EJB container as being roughly equivalent to the ORB in CORBA, with a few of the CORBA services thrown in as well. In EJB, however, the container is strictly a server-side entity. The client doesn't need its own container to use EJB objects, but an EJB object needs to have a container in order to be available for client use. Figure 6-1. The basic roles in an EJB environment6.2.1. The Enterprise JavaBeans ObjectAt the heart of an EJB component is the actual implementation object. The EJB implementation class is where the real value of the EJB liesthe business methods that clients want to invoke are implemented here. The EJB object:
6.2.1.1. Types of EJBsThe three fundamental types of Enterprise JavaBeans are session, entity, and message-driven. The key difference between these component models lies in how they are managed during their lifetime by the EJB container and what component services are available to them through the container. Before implementing an EJB component, it's important to understand these different types and decide which one is most appropriate for a particular situation.
To illustrate the differences between session, entity, and message-driven beans , suppose you're building an online banking system using EJB components. An automated teller machine, which reports on account balances and executes deposits and withdrawals on specified accounts, could be implemented as a session bean. A single client uses the teller bean to perform services on bank accounts that are maintained in some separate persistent store (the bank's database). An EJB object that directly represents a bank account, however, should be an entity bean. Multiple clients can access the account to perform transactions, and the state of the account entity should be persistent across the lifetime of the online banking server. If we want to provide wireless access to the banking system from PDAs or mobile phones, we might have these devices communicate with the system using lightweight, asynchronous messaging, since their network connectivity is typically unstable and low in bandwidth. This may lead us to use message-driven EJBs, which can respond to these client messages but still take advantage of the lifecycle management capabilities of the EJB container. 6.2.1.2. EJB code artifactsAt a minimum, an EJB component consists of an implementation class that is deployed to the EJB container, plus a deployment descriptor that tells the EJB container how to manage the component. Depending on the specific type of EJB you are implementing, the EJB may also need to include one or more client interfaces and server-side support classes required for the EJB container to manage the component. Specifically, a message-driven bean requires only an implementation class and a deployment descriptor. These beans are seen by clients as JMS destinations to which they send messages, so there's no need for client interfaces for these EJBs . Session beans are created by clients using their home interface(s) and operated by clients using their client interfaces, so these interfaces (in addition to the implementation class and deployment descriptor) are required when implementing session EJBs. Entity EJBs are the most complex to implement because they make the most use of the EJB container's services. In addition to the implementation class, home interface(s), client interface(s), and deployment descriptor, an entity bean may also require a primary key class. Entity beans also have a significant amount of additional information in their deployment descriptors, related to their persistence properties. 6.2.2. The EJB ClientAn EJB client uses EJB objects to access data, perform tasks, and generally get things done. In the EJB environment, the first action a client performs is to find the home interface for the type of EJB object that it wants to use. This home interface is a kind of object factory, used to create new instances of the EJB type, look up existing instances (only when using entity EJB objects, discussed later), and delete EJB objects. This is a bit different from RMI, in which the client first has to get a direct handle to an existing RMI servant. In many RMI applications, this first RMI object is a kind of object factory that is used to create other RMI object references. So, in a sense, the use of home interfaces in EJB is just formalizing the role of factory objects in distributed component applications. EJB home interfaces are located by clients using JNDI (described in Chapter 9), the same way that other J2EE resources like JDBC DataSources and JMS ConnectionFactory resources are accessed. An EJB server publishes the home interface for a particular EJB object under a particular name in a JNDI namespace. The EJB client needs to connect to the JNDI server and look up the EJB home interface under the appropriate name in order to start things off. We'll see concrete examples of EJB clients a bit later in the chapter, but here is a summary of the fundamental steps an EJB client performs:
6.2.3. The EJB ContainerMost readers need to be familiar with EJB containers only from the perspective of an EJB client or an EJB object. A J2EE application server provides an internal EJB container, along with other required aspects of the J2EE framework. EJB-enabled application servers, with their own EJB containers and deployment tools, are available from BEA, JBoss, IBM, Sun, and many others. The EJB container supplies the value-added features that EJB provides over standard remote objects built using RMI or CORBA. The EJB container manages the lifecycle of your EJBs and all the details of transaction processing, security, resource pooling, and data persistence. For components that require these services, the use of the EJB container reduces the burden on both client applications and EJB objects, allowing them to deal with just the business at hand. An EJB container is the heart of an EJB environment, in the same way that an ORB is the heart of a CORBA environment or a web server is the heart of a web environment. As depicted in Figure 6-1, all runtime interactions between the clients and the EJB objects themselves are mediated by the EJB container (although from the client's perspective, it seems as though they are interacting directly with the EJB component itself). The EJB container takes all of the elements that make up your EJB (the implementation class, any client interfaces, etc.) and a deployment descriptor, and it uses these to generate the various support classes needed to manage and run the EJB component, as shown in Figure 6-2. You provide any needed home and client interfaces, and the container generates both the client and the server-side implementations for these interfaces. As the figure shows, EJBs can support both local and remote clients. When a remote client looks up a session or entity bean's remote home interface through JNDI, it receives an instance of a remote stub class. All methods invoked on this stub are remotely invoked, via RMI or IIOP, on the corresponding home implementation object on the EJB server. Similarly, if the client creates or finds any beans through the remote home stub, the client receives remote object stubs, and methods invoked on the stubs are passed through RMI or IIOP to corresponding implementation objects on the server. These remote objects are linked, through the EJB container, to a corresponding enterprise bean object, which is an instance of your bean implementation class. Local clients interact with EJBs in a simplified, more efficient way. Local home objects and bean interfaces are obtained the same way as remote ones, but the objects obtained are nonremote objects that interact locally (i.e., from within the same Java virtual machine) with their EJB implementations. Note that Figure 6-2 demonstrates the situation for session and entity beans. Message-driven beans are accessed by clients using JMS messages sent to a JMS destination, and EJBs that are published as web services are invoked by clients using SOAP calls. So in both of these cases, clients do not need home or client interfaces. Details on JMS and SOAP clients can be found in Chapters 11 and 12, respectively. It's important to remember that all client requests to create, look up, delete, or call methods on EJBs are mediated by the EJB container. It either handles them itself or passes the requests to corresponding methods on to the EJB object. Once the client obtains a reference to an interface for an EJB object, the container intercedes in all method calls to the bean to provide the bean with required services (transaction management, lifecycle management, and security) and to notify the bean of any events related to these services (for example, the bean needing to reload its persistent data or the bean instance being destroyed by the container). Figure 6-2. Relationship of bean-provider classes and container-generated classesWhen you deploy an EJB object within an EJB server, you use deployment descriptors to specify how the container should manage the bean during runtime, in terms of all the services the container provides. Deployment descriptors contain parameter settings for these various options. These settings can be customized for each deployment of an EJB object. You might purchase an EJB object from a vendor and deploy it on your EJB server with a particular set of container management options while someone else who purchased the same bean can deploy it with a different set of deployment options. We discuss the details of the runtime options available in deployment descriptors and how to use them later in this chapter when we talk about deploying EJB components. |