Java Service Locator Pattern(服务器定位模式)

简介: 服务定位器模式(Service Locator Pattern)用在我们想使用 JNDI 查询定位各种服务的时候。考虑到为某个服务查找 JNDI 的代价很高,服务定位器模式充分利用了缓存技术。

服务定位器模式(Service Locator Pattern)用在我们想使用 JNDI 查询定位各种服务的时候。考虑到为某个服务查找 JNDI 的代价很高,服务定位器模式充分利用了缓存技术。在首次请求某个服务时,服务定位器在 JNDI 中查找服务,并缓存该服务对象。当再次请求相同的服务时,服务定位器会在它的缓存中查找,这样可以在很大程度上提高应用程序的性能。以下是这种设计模式的实体。

  • 服务(Service) - 实际处理请求的服务。对这种服务的引用可以在 JNDI 服务器中查找到。
    Context / 初始的 Context - JNDI Context 带有对要查找的服务的引用。
  • 服务定位器(Service Locator) - 服务定位器是通过 JNDI 查找和缓存服务来获取服务的单点接触。
  • 缓存(Cache) - 缓存存储服务的引用,以便复用它们。
  • 客户端(Client) - Client 是通过 ServiceLocator 调用服务的对象。
  1. 创建服务接口 Service。
/**
 * 1. 创建服务接口 Service。
 * @author mazaiting
 */
public interface Service {
    public String getName();
    public void execute();
}
  1. 创建实体服务。
/**
 * 2. 创建实体服务。
 * @author mazaiting
 */
public class Service1 implements Service{

    public String getName() {
        return "Service1";
    }

    public void execute() {
        System.out.println("Executing Service1");       
    }

}

/**
 * 2. 创建实体服务。
 * @author mazaiting
 */
public class Service2 implements Service{

    public String getName() {
        return "Service2";
    }

    public void execute() {
        System.out.println("Executing Service2");       
    }

}
  1. 为 JNDI 查询创建 InitialContext。
/**
 * 3. 为 JNDI 查询创建 InitialContext。
 * @author mazaiting
 */
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;
    }
}
  1. 创建缓存 Cache。
/**
 * 4. 创建缓存 Cache。
 * @author mazaiting
 */
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  "+service+" 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);
        }
    }
    
}
  1. 创建服务定位器。
/**
 * 5. 创建服务定位器。
 * @author mazaiting
 */
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;        
    }
    
}
  1. 使用 ServiceLocator 来演示服务定位器设计模式。
/**
 * 6. 使用 ServiceLocator 来演示服务定位器设计模式。
 * @author mazaiting
 */
public class Client {
    
    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();      
    }
    
}
  1. 打印结果
Looking up and creating a new Service1 object
Executing Service1
Looking up and creating a new Service2 object
Executing Service2
Returning cached  com.mazaiting.serloc.Service1@15db9742 object
Executing Service1
Returning cached  com.mazaiting.serloc.Service2@6d06d69c object
Executing Service2
目录
相关文章
|
12天前
|
监控 算法 Java
jvm-48-java 变更导致压测应用性能下降,如何分析定位原因?
【11月更文挑战第17天】当JVM相关变更导致压测应用性能下降时,可通过检查变更内容(如JVM参数、Java版本、代码变更)、收集性能监控数据(使用JVM监控工具、应用性能监控工具、系统资源监控)、分析垃圾回收情况(GC日志分析、内存泄漏检查)、分析线程和锁(线程状态分析、锁竞争分析)及分析代码执行路径(使用代码性能分析工具、代码审查)等步骤来定位和解决问题。
|
2月前
|
Java 程序员 测试技术
Java|让 JUnit4 测试类自动注入 logger 和被测 Service
本文介绍如何通过自定义 IDEA 的 JUnit4 Test Class 模板,实现生成测试类时自动注入 logger 和被测 Service。
29 5
|
2月前
|
消息中间件 分布式计算 监控
大数据-78 Kafka 集群模式 集群的应用场景与Kafka集群的搭建 三台云服务器
大数据-78 Kafka 集群模式 集群的应用场景与Kafka集群的搭建 三台云服务器
81 6
|
2月前
|
Java
Java面试题之cpu占用率100%,进行定位和解决
这篇文章介绍了如何定位和解决Java服务中CPU占用率过高的问题,包括使用top命令找到高CPU占用的进程和线程,以及使用jstack工具获取堆栈信息来确定问题代码位置的步骤。
120 0
Java面试题之cpu占用率100%,进行定位和解决
|
2月前
|
SQL 存储 数据管理
Hadoop-15-Hive 元数据管理与存储 Metadata 内嵌模式 本地模式 远程模式 集群规划配置 启动服务 3节点云服务器实测
Hadoop-15-Hive 元数据管理与存储 Metadata 内嵌模式 本地模式 远程模式 集群规划配置 启动服务 3节点云服务器实测
61 2
|
2月前
|
存储 Java
深入理解java对象的访问定位
这篇文章深入探讨了Java对象的访问定位机制,比较了使用句柄和直接指针两种主流的对象访问方式,并指出了它们各自的优势,例如句柄访问在对象移动时的稳定性和直接指针访问的速度优势。
35 0
深入理解java对象的访问定位
|
3月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:如何提高代码的可维护性与扩展性在软件开发领域,PHP 是一种广泛使用的服务器端脚本语言。随着项目规模的扩大和复杂性的增加,保持代码的可维护性和可扩展性变得越来越重要。本文将探讨 PHP 中的设计模式,并通过实例展示如何应用这些模式来提高代码质量。
设计模式是经过验证的解决软件设计问题的方法。它们不是具体的代码,而是一种编码和设计经验的总结。在PHP开发中,合理地使用设计模式可以显著提高代码的可维护性、复用性和扩展性。本文将介绍几种常见的设计模式,包括单例模式、工厂模式和观察者模式,并通过具体的例子展示如何在PHP项目中应用这些模式。
|
2月前
|
弹性计算 应用服务中间件 网络安全
ECS服务器使用:SSL证书安装、配置和问题定位指南
本文简要介绍了SSL证书的生成与部署方法,包括使用OpenSSL生成自签名证书和从CA获取证书的步骤,以及在Apache和Nginx服务器上的配置方法。此外,还提供了测试证书是否生效的方法和常见问题的解决策略,帮助确保证书正确安装并解决调试过程中可能遇到的问题。
180 0
|
2月前
|
Java 数据库
基于java的汽车服务管理系统(Car Service Management System)
基于java的汽车服务管理系统(Car Service Management System)
24 0
|
3月前
|
存储 Java 开发者
【Java新纪元启航】JDK 22:解锁未命名变量与模式,让代码更简洁,思维更自由!
【9月更文挑战第7天】JDK 22带来的未命名变量与模式匹配的结合,是Java编程语言发展历程中的一个重要里程碑。它不仅简化了代码,提高了开发效率,更重要的是,它激发了我们对Java编程的新思考,让我们有机会以更加自由、更加创造性的方式解决问题。随着Java生态系统的不断演进,我们有理由相信,未来的Java将更加灵活、更加强大,为开发者们提供更加广阔的舞台。让我们携手并进,共同迎接Java新纪元的到来!
70 11