Defining Client Access with Interfaces
Note: The material in this section applies only to session and entity beans, not to message-driven beans. Because they have a different programming model, message-driven beans do not have interfaces that define client access.
A client may access a session or an entity bean only through the methods defined in the bean's interfaces. These interfaces define the client's view of a bean. All other aspects of the bean--method implementations, deployment descriptor settings, abstract schemas, and database access calls--are hidden from the client.
Well-designed interfaces simplify the development and maintenance of J2EE applications. Not only do clean interfaces shield the clients from any complexities in the EJB tier, but they also allow the beans to change internally without affecting the clients. For example, even if you change your entity beans from bean-managed to container-managed persistence, you won't have to alter the client code. But if you were to change the method definitions in the interfaces, then you might have to modify the client code as well. Therefore, to isolate your clients from possible changes in the beans, it is important that you design the interfaces carefully.
When you design a J2EE application, one of the first decisions you make is the type of client access allowed by the enterprise beans: remote or local.
A remote client of an enterprise bean has the following traits:
- It may run on a different machine and a different Java 2 virtual machine (JVM) than the enterprise bean it accesses. (It is not required to run on a different JVM.)
- It can be a Web component, a J2EE application client, or another enterprise bean.
- To a remote client, the location of the enterprise bean is transparent.
To create an enterprise bean with remote access, you must code a remote interface and a home interface. The remote interface defines the business methods that are specific to the bean. For example, the remote interface of a bean named
BankAccountEJBmight have business methods named
debitand credit. The home interface defines the bean's life cycle methods--
remove. For entity beans, the home interface also defines finder methods and home methods. Finder methods are used to locate entity beans. Home methods are business methods that are invoked on all instances of an entity bean class. Figure 3-2 shows how the interfaces control the client's view of an enterprise bean.
Figure 3-2 Interfaces for an Enterprise Bean With Remote Access
A local client has these characteristics:
- It must run in the same JVM as the enterprise bean it accesses.
- It may be a Web component or another enterprise bean.
- To the local client, the location of the enterprise bean it accesses is not transparent.
- It is often an entity bean that has a container-managed relationship with another entity bean.
To build an enterprise bean that allows local access, you must code the local interface and the local home interface. The local interface defines the bean's business methods, and the local home interface defines its life cycle and finder methods.
Local Interfaces and Container-Managed Relationships
If an entity bean is the target of a container-managed relationship, then it must have local interfaces. The direction of the relationship determines whether or not a bean is the target. In Figure 3-1, for example,
ProductEJBis the target of a unidirectional relationship with
ProductEJBmust have the local interfaces.
LineItemEJBalso needs local interfaces--not because of its relationship with
ProductEJB--but because it is the target of a relationship with
OrderEJB. And because the relationship between
OrderEJBis bidirectional, both beans must have local interfaces.
Because they require local access, entity beans that participate in a container-managed relationship must reside in the same EJB JAR file. The primary benefit of this locality is increased performance--local calls are usually faster than remote calls.
Deciding on Remote or Local Access
The decision regarding whether to allow local or remote access depends on the following factors.
Container-managed relationships: If an entity bean is the target of a container-managed relationship, it must use local access.
Tight or loose coupling of related beans: Tightly coupled beans depend on one another. For example, a completed sales order must have one or more line items, which cannot exist without the order to which they belong. The
LineItemEJBentity beans that model this relationship are tightly coupled. Tightly coupled beans are good candidates for local access. Since they fit together as a logical unit, they probably call each other often and would benefit from the increased performance that is possible with local access.
Type of client: If an enterprise bean is accessed by J2EE application clients, then it should allow remote access. In a production environment, these clients almost always run on different machines than the J2EE server. If an enterprise bean's clients are Web components or other enterprise beans, then the type of access depends on how you want to distribute your components.
Component distribution: J2EE applications are scalable because their server-side components can be distributed across multiple machines. In a distributed application, for example, the Web components may run on a different server than the enterprise beans they access. In this distributed scenario, the enterprise beans should allow remote access.
If you aren't sure which type of access an enterprise bean should have, then choose remote access. This decision gives you more flexibility--in the future you can distribute your components to accommodate growing demands on your application.
Although uncommon, it is possible for an enterprise bean to allow both remote and local access. Such a bean would require both remote and local interfaces.
Performance and Access
Because of factors such as network latency, remote calls may be slower than local calls. On the other hand, if you distribute components among different servers, you might improve the application's overall performance. Both of these statements are generalizations; actual performance can vary in different operational environments. Nevertheless, you should keep in mind how your application design might affect performance.
Method Parameters and Access
The type of access affects the parameters of the bean methods that are called by clients. The following topics apply not only to method parameters, but also to method return values.
An argument in a remote call is passed by value; it is a copy of an object. But an argument in a local call is passed by reference, just like a normal method call in the Java programming language.
The parameters of remote calls are more isolated than those of local calls. With remote calls, the client and bean operate on different copies of a parameter object. If the client changes the value of the object, the value of the copy in the bean does not change. This layer of isolation can help protect the bean if the client accidentally modifies the data.
In a local call, both the client and the bean may modify the same object. In general, you should not rely on this side effect of local calls. Perhaps some day you will want to distribute your components, replacing the local calls with remote ones.
Granularity of Accessed Data
Because remote calls are likely to be slower than local calls, the parameters in remote methods should be relatively coarse-grained. Since a coarse-grained object contains more data than a fine-grained one, fewer access calls are required.
For example, suppose that a
CustomerEJBentity bean is accessed remotely. This bean would have a single getter method that returns a
CustomerDetailsobject, which encapsulates all of the customer's information. But if
CustomerEJBis to be accessed locally, it could have a getter method for each instance variable:
getPhoneNumber, and so forth. Because local calls are fast, the multiple calls to these finer-grained getter methods would not significantly degrade performance.