zoukankan      html  css  js  c++  java
  • Java SPI机制和使用示例

    JAVA SPI 简介

    SPI 是 Java 提供的一种服务加载方式,全名为 Service Provider Interface。根据 Java 的 SPI 规范,我们可以定义一个服务接口,具体的实现由对应的实现者去提供,即服务提供者。然后在使用的时候再根据 SPI 的规范去获取对应的服务提供者的服务实现。通过 SPI 服务加载机制进行服务的注册和发现,可以有效的避免在代码中将服务提供者写死。从而可以基于接口编程,实现模块间的解耦。

    SPI 机制的约定

    1 在 META-INF/services/ 目录中创建以接口全限定名命名的文件,该文件内容为API具体实现类的全限定名

    2 使用 ServiceLoader 类动态加载 META-INF 中的实现类

    3 如 SPI 的实现类为 Jar 则需要放在主程序 ClassPath 中

    4 API 具体实现类必须有一个不带参数的构造方法

    SPI 应用场景举例

    JDBC

    jdbc4.0以前, 开发人员还需要基于Class.forName("xxx")的方式来装载驱动,jdbc4也基于spi的机制来发现驱动提供商了,可以通过METAINF/services/java.sql.Driver文件里指定实现类的方式来暴露驱动提供者.

    COMMON-LOGGING

    apache最早提供的日志的门面接口。只有接口,没有实现。具体方案由各提供商实现, 发现日志提供商是通过扫描METAINF/services/org.apache.commons.logging.LogFactory配置文件,通过读取该文件的内容找到日志提工商实现类。只要我们的日志实现里包含了这个文件,并在文件里制定 LogFactory工厂接口的实现类即可。

    SPI 机制代码示例

    接口 People.java

    package org.louis.spi.test;
    
    public interface People {
    public String speak();
    }

    实现类 Chinese.java

    package org.louis.spi.test;
     
    public class Chinese implements People{
    
        public String speak() {
     
            return "Chinese speak Chinese.";
     
        }
     
    }

    实现类 American.java

    package org.louis.spi.test;
     
    public class American implements People{
    
        public String speak() {
     
            return "American speak English.";
     
        }
     
    }

    创建一个文件,放置到 META-INF/Services 目录:

    文件名:org.louis.spi.test.People

    文件内容:

    org.louis.spi.test.Chinese
    org.louis.spi.test.American

    新建一个测试工程,引入以上代码生成的Jar包

    测试类SpiTest.java

    package org.louis.test;
     
    import java.util.Iterator;
    import java.util.ServiceLoader;
     
    import org.louis.spi.test.People;
    import org.louis.spi.test.Chinese;
    import org.louis.spi.test.American;
    public class SpiTest { public static void main(String[] args) {
    ServiceLoader<People> peoples = ServiceLoader.load(People.class);
    Iterator<IOperation> iterator = peoples.iterator();
           while (iterator.hasNext()) { People people = iterator.next(); System.out.println(people.speak()); } } }

    运行结果:

    Chinese speak Chinese.

    American speak English.

     

    通过上面例子,我们看到,假如我要新加入一个韩国人的实现,那只需要新建一个新的工程,创建一个Koeran类实现People接口,并在自己工程 META-INF/Services 目录下放置一个配置文件指定Koeran实现类,将工程打成Jar包,就完成了一个新的服务实现的开发。


    作者:朝雨忆轻尘
    出处:https://www.cnblogs.com/xifengxiaoma/ 
    版权所有,欢迎转载,转载请注明原文作者及出处。

     

  • 相关阅读:
    HDU 1507 Uncle Tom's Inherited Land*
    HDU 2527 Safe Or Unsafe (哈夫曼树)
    HDU More lumber is required
    HDU Machine Schedule
    HDU 3709 Balanced Number (数位DP)
    HDU Number Sequence (容斥原理)
    csharp: word or excel Convert to PDF
    csharp: winform using Microsoft.Ink(Tablet PC API) create Signature image
    Create Ms Word doc using Javascript And vbscript
    sql distinct
  • 原文地址:https://www.cnblogs.com/xifengxiaoma/p/9443922.html
Copyright © 2011-2022 走看看