JAVA基础(二)Service Locator
JAVA基础(二)Service Locator
note of http://java.sun.com/blueprints/patterns/ServiceLocator.html
Service Locator
brief description
The Service Locator pattern centralizes distributed service object lookups, provides a centralized point of control, and may act as a cache that eliminates redundant lookups. It also encapsulates any vendor-specific features of the lookup process.
Detailed Description
Detailed Example
EJB tier sample code
http://download.oracle.com/docs/cd/E17802_01/blueprints/blueprints/code/jps131/src/com/sun/j2ee/blueprints/servicelocator/ejb/ServiceLocator.java.html
WEB tier sample code
http://download.oracle.com/docs/cd/E17802_01/blueprints/blueprints/code/jps131/src/com/sun/j2ee/blueprints/servicelocator/web/ServiceLocator.java.html
The only difference between them is that the Web-tier class is a singleton, and it caches the objects it looks up. The EJB-tier class is not a singleton, and does not cache.
In the sample, AdminRequestBD calls the ServiceLocator static method getInstance to get the singleton instance of the service locator, then calls getRemoteHome to get the remote home interface of the OPCAdminFacade enterprise bean.
Improving performance with the Singleton pattern and caching
The meaning of the term "singleton" is not always clear in a distributed environment; in ServiceLocator it means that only one instance of the class exists per class loader.
The Singleton pattern improves performance because it eliminates unnecessary construction of ServiceLocator objects,JNDI InitialContext objects, and enables caching.
The Web-tier service locator alse improves performance by caching the objects it finds. The cache lookup ensures that a JNDI lookup only occurs once for each name. Subsequent lookups come from the cache, which is typically much faster than a JNDI lookup.
public class ServiceLocator {
private InitialContext ic;
private Map cache;
private static ServiceLocator me;
static {
try {
me = new ServiceLocator();
} catch(ServiceLocatorException se) {
System.err.println(se);
se.printStackTrace(System.err);
}
}
private ServiceLocator() throws ServiceLocatorException {
try {
ic = new InitialContext();
cache = Collections.synchronizedMap(new HashMap());
} catch (NamingException ne) {
throw new ServiceLocatorException(ne);
}
}
static public ServiceLocator getInstance() {
return me;
}
public EJBHome getRemoteHome(String jndiHomeName, Class className) throws ServiceLocatorException {
EJBHome home = null;
try {
if (cache.containsKey(jndiHomeName)) {
home = (EJBHome) cache.get(jndiHomeName);
} else {
Object objref = ic.lookup(jndiHomeName);
Object obj = PortableRemoteObject.narrow(objref, className);
home = (EJBHome)obj;
cache.put(jndiHomeName, home);
}
} catch (NamingException ne) {
throw new ServiceLocatorException(ne);
} catch (Exception e) {
throw new ServiceLocatorException(e);
}
return home;
}