SPI机制| 8月更文挑战

225 阅读1分钟

全称:Service Provider Interface 服务发现机制.它可以用于实现框架扩展或者组件替换.

本质

SPI的核心思想就是解耦

将接口实现类的全限定名配置在文件中,并且由服务器读取配置文件,这样就可以加载写入的实现类,运行中就可以动态替换接口实现类.

位置

META-INF/services 下面定义配置文件,通过特殊的类加载器,启动的时候加载文件中定义的类.

这个位置在ServiceLoader加载器中定义了,因此位置无法改变

策略模式-源码.png PREFIX+实现类全限定名,即可找到对应的实现类

文件名为实现类的接口的全限定名,内容为实现类的全限定名

策略模式0.png

使用ServiceLoader.load加载Animals这个接口的实现类迭代器(文件中配置的实现类都会加载在上面).

通过迭代器,可以获取所有类.

			// 1.通过load获得类的列表
        ServiceLoader<Animals> load = ServiceLoader.load(Animals.class);
        // 2. 迭代器遍历
        Iterator iterator = load.iterator();
        while (iterator.hasNext()) {
            Animals next = (Animals) iterator.next();
            System.out.println(next.toString());
        }

当配置文件中只有一个类时,那么最后也只会展示一个类的信息;

策略模式.png

11.png

通过这个配置文件,我们可以通过改变配置文件来动态改变类的信息.

这个可以使用在策略模式中

策略模式SPI实现开闭原则

直接迭代实现类,并且进行判断获得对应的对象

public static Animals getAnimals(String type) {
        ServiceLoader<Animals> load = ServiceLoader.load(Animals.class);
        Iterator<Animals> iterator = load.iterator();
        while(iterator.hasNext()) {
            Animals animals = iterator.next();
            if (type.equals(animals.typeName())) {
                return animals;
            }
        }
        return null;
    }

执行

public static void main(String[] args) {
        Animals 松鼠 = SPIAnimalsFactory.getAnimals("松鼠");
        System.out.println("松鼠:"+松鼠);

        Animals 熊猫 = SPIAnimalsFactory.getAnimals("熊猫");
        System.out.println("熊猫:"+熊猫);

    }

结果:

松鼠:Songshu{name='松鼠',foodType='松果',songguoNum=10} 熊猫:Panda{name='熊猫',foodType='竹子',zhuziName=20}