Patterns have become very important and indespensible for Architects and Programmers. This is because provide reusable solutions to recurring problems in different contexts and also provide a language to describe them. The important point here is reuability of the same solution again and again .
J2EE provides its own set of patterns, other than the core design patterns. I have been working on the J2EE patterns for the past few weeks. The ServiceLocator pattern interests me a lot. This pattern tries to encapsulate complex interfaces and network operations to service lookup and creation. The basic aim of this article is to provide an implementation to this pattern. The aim is to be able to reuse this same class over different projects in J2EE without code change.
All J2EE clients that want to access components like EJB’s, JMS Queues and DataSource need to access them through a lookup. A typical lookup involves the following
InitialContext ic= new InitialContext(); ABCHome home=(ABCHome) ic.lookup(“ABCHome” ;) ;For EJB lookup’s addition actions like PortableRemoteObject.narrow() need to be invoked.
The above lines of code recur again and again in the web layer that accesses the Business layer. This type of code may also recur in the Business layer as one EJB access another like in the Business Fašade pattern. This can cause the following problems
ABCHome home = (ABCHome) ServiceLocator.getInstance().getHome(“ABCHome”, ABCHome.class , true) ;Types of Clients of ServiceLocator
Servlce Lookup Strategies
There following strategies can be followed in the ServiceLocator Pattern.
1. The lookup Names exist in the Web layer or Business layer. In this scenario the JNDI name to be looked up are passed from this layer. The problem here is that multiple objects looking up the same object may hardcode the lookup names in code like in the line 1 above. This is the same problem that we talked of earlier. To solve this problem one can look up the JNDI names and other properties through a property file. This is very easy to implement and solves the problem.
2. A second solution introduces the concept of services and in this case we move the lookup specific variables into a Services class. A service encapsulates the users from the complexities like JNDI names, Home class names , remote class names etc. The requestor of the services knows just the service which is defined in the Services class. This is something like
Services.CustomerServiceThis is passed to the ServiceLocator class. The service locater API then determines based on the service what all parameters it requires and get this from the services class. The Service specific parameters can be in the ServiceLocator class,or in an inner class or in a different class. We here have implemented this in a totally new class with package access. This is to prevent others from modifying the main ServiceLocator class. Package access has been provided to the methods of the Services class so that the ServiceLocator class can access them. Other classes can only access the public defined services of Services class. The properties can also be got from a properties file.
In both the cases the properties file strategy is recommended so that changes to code need not be done in case of change in properties.
In this case the ServiceLocator can be invoked as follows
ABCHome home = (ABCHome) ServiceLocator.getInstance().getHome(ServiceLocator. CustomerService, true);Cached / UnCached Lookups
There are also two types of Service lookups through the ServiceLocater. These two types are Cached and UnCached lookups.
The Cached lookups can be made through passing the a Boolean of true to all lookup methods for the pFromCache parameter
The Uncached lookups can be made through passing a Boolean of false to all lookup method for the pFromCache parameter.
Another difference between Cached and Uncached lookups is that the Uncached lookups do not create the Cache. Thus the first time a Cached lookup Is made a JNDI lookup will take place even though a Uncached lookup has been made earlier for the same service.
Lets talk “implementation”
The implementation thus
1) Undertakes JNDI Lookups for various objects like
Core J2EE Patterns
There is a Java class too and here is the code