JAVA中的SPI机制

作者: a21455ce3dba | 来源:发表于2017-08-28 15:57 被阅读6次

    原理

    参考
    http://singleant.iteye.com/blog/1497259

    简单来说,这是 JAVA 提供给服务提供厂商的一个实现机制,和 IOC 一样具有解耦的作用。

    例如我们知道 JDBC 是 JAVA 官方实现的一个数据库接口规范,但是嘛,数据库有很多,例如 MySQL,Oracle等等。

    很久以前没有 JDBC 的时候,我们更换数据库就要更改很多数据库的操作代码。

    后来 JAVA 官方指定了 JDBC 标准。我们编程的时候使用 JDBC 规范里面提供的接口就好, 由 MySQl ,Oracle按照JDBC来实现的数据库驱动。 这样的话我们更换数据库的时候就几乎不用重新修改原有代码了,只需要更换一个数据库驱动的jar包。

    想起一句话:JAVA的世界里,规范和实现是分离的

    例子

    实现

    搜索接口

    package com.search;
    
    import java.util.List;
    
    /**
     * Created by yaoyong.dyy@alibaba-inc.com on 2017/8/24.
     */
    public interface ISearch {
        public String searchByKeyWord();
    }
    

    搜索可以使用数据库提供的搜索,也可以使用文件系统提供的搜索

    数据库提供的搜索实现

    package org.B;
    
    import com.search.ISearch;
    
    /**
     * Created by yaoyong.dyy@alibaba-inc.com on 2017/8/24.
     */
    public class DBSearch implements ISearch {
        @Override
        public String searchByKeyWord() {
            return "DBSearch is searching";
        }
    }
    
    

    文件系统提供的搜索实现

    package org.A;
    
    import com.search.ISearch;
    
    /**
     * Created by yaoyong.dyy@alibaba-inc.com on 2017/8/24.
     */
    public class FileSearch implements ISearch{
        @Override
        public String searchByKeyWord() {
            return "FileSearch is searching";
        }
    }
    
    

    调用搜索

    package com.search;
    
    import java.util.Iterator;
    import java.util.ServiceLoader;
    
    /**
     * Created by yaoyong.dyy@alibaba-inc.com on 2017/8/24.
     */
    public class Main {
        public static void main(String[] args) {
            ServiceLoader<ISearch> sloader = ServiceLoader.load(ISearch.class);
            Iterator<ISearch> it = sloader.iterator();
            while (it.hasNext()) {
                ISearch curSearch = it.next();
                String result = curSearch.searchByKeyWord();
                System.out.println(result);
            }
        }
    }
    
    

    项目结构

    项目结构

    其中 META-INF/services 的目录名是不能变的诶~~~,因为在JDK中已经硬编码了,请看 ServiceLoader的源代码

    源码

    调用过程

    两个实现 只有一个实现

    相关文章

      网友评论

        本文标题:JAVA中的SPI机制

        本文链接:https://www.haomeiwen.com/subject/oudgdxtx.html