Reference to this article Rookie tutorial and ThinkWon Explanation of single example mode of:
The Service Locator Pattern is used when we want to use JNDI query to locate various services. Considering the high cost of finding JNDI for a service, the Service Locator Pattern makes full use of caching technology. When a service is first requested, the service locator finds the service in JNDI and caches the service object. When the same service is requested again, the service locator will look in its cache, which can greatly improve the performance of the application. The following are the entities of this design pattern.
- Service - the service that actually handles the request. A reference to this service can be found in the JNDI server.
Context / initial Context - JNDI Context has a reference to the service to be found. - Service Locator - a service locator is a single point of contact for obtaining services through JNDI lookup and caching services.
- Cache - caches references to storage services in order to reuse them.
- Client - a client is an object that invokes a service through ServiceLocator.
achieve
We will create ServiceLocator, InitialContext, Cache and service as various objects representing entities. Service1 and Service2 represent entity services.
ServiceLocatorPatternDemo, our demo class here is used as a client to demonstrate the service locator design pattern.
Service interface:
public interface Service { public String getName(); public void execute(); }
Service1 class:
public class Service1 implements Service { public void execute(){ System.out.println("Executing Service1"); } @Override public String getName() { return "Service1"; } }
Service2 class:
public class Service2 implements Service { public void execute(){ System.out.println("Executing Service2"); } @Override public String getName() { return "Service2"; } }
InitialContext class:
public class InitialContext { public Object lookup(String jndiName){ if(jndiName.equalsIgnoreCase("SERVICE1")){ System.out.println("Looking up and creating a new Service1 object"); return new Service1(); }else if (jndiName.equalsIgnoreCase("SERVICE2")){ System.out.println("Looking up and creating a new Service2 object"); return new Service2(); } return null; } }
Cache class:
import java.util.ArrayList; import java.util.List; public class Cache { private List<Service> services; public Cache(){ services = new ArrayList<Service>(); } public Service getService(String serviceName){ for (Service service : services) { if(service.getName().equalsIgnoreCase(serviceName)){ System.out.println("Returning cached "+serviceName+" object"); return service; } } return null; } public void addService(Service newService){ boolean exists = false; for (Service service : services) { if(service.getName().equalsIgnoreCase(newService.getName())){ exists = true; } } if(!exists){ services.add(newService); } } }
ServiceLocator class:
public class ServiceLocator { private static Cache cache; static { cache = new Cache(); } public static Service getService(String jndiName){ Service service = cache.getService(jndiName); if(service != null){ return service; } InitialContext context = new InitialContext(); Service service1 = (Service)context.lookup(jndiName); cache.addService(service1); return service1; } }
ServiceLocatorPatternDemo class:
public class ServiceLocatorPatternDemo { public static void main(String[] args) { Service service = ServiceLocator.getService("Service1"); service.execute(); service = ServiceLocator.getService("Service2"); service.execute(); service = ServiceLocator.getService("Service1"); service.execute(); service = ServiceLocator.getService("Service2"); service.execute(); } }