EJB best practices: Dynamic Delegation
Use JavaReflectionBuild more general business delegation
Level: Intermediate
Brett McLaughlin (brett@oreilly.com)
Writer and editor, o'reilly and Associates
March 2003
Although the Business Delegate class does bring exciting new flexibility to your Enterprise Java design, it can be applied to youProgramIt is too troublesome to encode a service delegate for each session bean in. This article in The EJB Best Practices SeriesArticleBrett McLaughlin shows you how to create a more common version of the Business Delegate class: Dynamic delegate.
In the previous article, we discussed how to use a Business Delegate class (do not confuse the business interface mode) to access your EJB component. ThroughCodeInsert a Business Delegate class between the and EJB code. We can isolate the web layer of the application from the EJB semantics and business logic.
One way to study such design is to see how common it is. Starting with an application, the business logic and technical functions in the application are closely intertwined. We have gradually separated different layers of the application, and use different technologies to reduce their mutual dependencies. In doing so, you should find that the more common the underlying structure of an application, the more robust it will be over time and the better maintainability.
In this article, we will continue to use general design ideas. We will start with studying the limitations of current business delegation implementation, and then I will show you how to overcome these limitations by creating a more general (and thus less rigid) Business Delegate class implementation.
Business assignment: Review
Review the Business Delegate class of the library bean interface we discussed last month.
Most of the code of the librarydelegate class only copies the method of the original library bean. Librarydelegate adds the init (), destroy (), and constructor methods, and then delegates the task to the library bean using these methods. In this case, delegates act as the buffer between the web layer and the enterprise Bean. Here is the business interface of the original bean.
Method Reproduction
Unless you consider that multiple session beans have 10, 20, or more methods, the problem with this method is not obvious. In fact, it is not uncommon to find a session bean with 50 or more methods! Because the bean service interface must include all the methods of the bean, the Service delegate class will do the same. This will make the code too large and prone to errors.
Is your input too fast?
When using EJB components, we often copy many methods across remote interfaces, business interfaces, implementation classes, and current business delegate classes. Many of us prefer the cut and paste methods between the editor window and IDE, rather than entering them manually, but note the following: using option + V or control + V is as error-prone as you enter the method manually-the more methods you add, the more likely the error will be. By carefully checking whether you have correctly entered the methods and whether you have cut and pasted them as expected, you can avoid a lot of trouble.
In addition to the huge code, we must also consider the changing factors. Because the delegate class must copy all bean methods, and the bean will inevitably change over time, you will find that it takes a lot of time to add new methods to delegate, not to mention re-compilation. It is possible to test new code.
In itself, this does not seem to be a serious problem. But if we start to use the Business Delegate class to abstract the business and representation logic from the technical infrastructure (in this article, it refers to the EJB component. If you need to change the remote interface, our service delegate is still associated with the underlying components.
We need a better method. There are indeed better methods.
Dynamic Delegation
The solution is to use dynamic delegation, and it uses JavaReflection(Reflection ). You can enable the delegate to dynamically call methods on the remote interface of the target EJB component (through Java reflection API) without hard coding each business method to the delegate. In this way, the coupling from remote interfaces can be completely eliminated, because you do not need to make the corresponding changes in the service delegate when adding methods for bean businesses or remote interfaces. Using Dynamic delegation also makes it easier to change your technical infrastructure. To migrate from remote interfaces and EJB technology to another technology (such as Java Data Objects and JDO), you only need to change the delegate Init () method. All other method calls will continue to be delegates through the bean interface, and can continue to be used without further changes. Listing 1 shows the dynamic version of the library service delegate:
Listing 1. Service Delegation of library Bean
Package com. IBM. Library;
Import java. Lang. Reflect. method;
Import java. Lang. Reflect. invocationtargetexception;
Import java. RMI. RemoteException;
Import java. util. hashmap;
Import java. util. Map;
Import javax. EJB. createexception;
Import javax. Naming. namingexception;
Public class librarydelegate implements ilibrary {
Private ilibrary library;
Private map availablemethods;
Public librarydelegate (){
Init ();
}
Public void Init (){
// Look up and obtain our session bean
Try {
Libraryhome =
(Libraryhome) ejbhomefactory. getinstance (). Lookup (
"Java: COMP/ENV/EJB/libraryhome", libraryhome. Class );
Library = libraryhome. Create ();
// Get the methods available for use in proxying
Availablemethods = new hashmap ();
Method [] Methods = ilibrary. Class. getmethods ();
For (INT I = 0; I <methods. length; I ++ ){
Availablemethods. Put (methods [I]. getname (),
Methods [I]);
}
} Catch (namingexception e ){
Throw new runtimeexception (E );
} Catch (createexception e ){
Throw new runtimeexception (E );
} Catch (RemoteException e ){
Throw new runtimeexception (E );
}
}
// All the hard-coded methods are removed
Public object
Invoke (Object proxy, method, object [] ARGs)
Throws throwable {
Try {
// See if this is INIT () or destroy ()
If (method. getname (). Equals ("init ")){
Init ();
Return NULL;
} Else if (method. getname (). Equals ("Destroy ")){
Destroy ();
Return NULL;
} Else {
Method method =
(Method) availablemethods. Get (method. getname ());
// See if we found anything
If (method! = NULL ){
Return method. Invoke (library, argS );
} Else {
Throw new
Nosuchmethodexception ("the library does not" +
"Support the" + method. getname () + "method .");
}
}
} Catch (invocationtargetexception e ){
// We don't support throwing runtimeexceptions from ejbs
// Directly
If (E. gettargetexception () instanceof RemoteException ){
Throw new runtimeexception (E );
} Else {
Throw E. gettargetexception ();
}
}
}
Public void destroy (){
// In this case, do nothing
}
}
Dynamic delegation is an excellent solution to the coupling problem between delegates, beans and their business interfaces. However, it is not a perfect solution, nor is it always the best solution. Although you have gained great flexibility from this method, you have also paid the performance cost. JavaReflectionIt is not very fast, so you will feel some latency between calling invoke () and obtaining results. The static business delegation class shown in the previous article is a faster solution, but it makes the coupling between your business layer and the technical layer higher than you want. Therefore, when balancing the two options, the choice should be based on the design or performance. Dynamic delegation is a better choice when the application is designed to be more important than the overall performance. When performance is a more important factor, business delegation is a better choice.
You may find that you are using dynamic Delegation for intranet applications. on the Intranet, all machines are on the local network, and you will often add or change features. Original business delegation may be a better choice for e-commerce and customer-oriented applications. In both cases, you should have a better understanding of business delegation and how it works. Have a good time and have a good time. We will see you online!