Java SPI实现:ServiceLoader 的使用

SPI 释义

在Java中,SPI其实可以理解为一个接口规范,有点类似于你电脑的外设,以鼠标举例。电脑制造商只给你提供一个鼠标的插口,至于鼠标是什么牌子,什么形状,电脑不关心,只要鼠标能够满足接口规范就行了。SPI英文全程 Service Provider Interface,即服务提供的接口,其实就是基于Java接口服务的一种服务扩展机制而已,可以用来替换框架中的扩展和组件,如下图:


SPI 在Java中的实现(tip: 如果不明白实现,直接看使用示例就明白怎么玩了。)

Java 为解决 SPI 问题,在Java4的时候提供了一个服务加载类,即 ServiceLoader。ServiceLoader可以直接加载Jar按规定提供的服务接口实现,具体使用方式如下所示:

  1. 在类加载路径下,在目录META-INF/services下的文件(以Interface全路径命名)中添加具体实现类的全路径名;
  2. 接口的实现类放在程序的加载路径下。
  3. 实现接口实现类,特别注意:实现类必须提供一个无参构造方法。

Java SPI使用示例

1. 定义接口

package com.lm.service;

/**
 * @author Liu.Liangyuan
 * @version $Id: IService.java, v 0.1 2022年04月10日 8:35 下午 LiangMu Exp $$
 */
public interface IService {
    void sayHello();
}

2. 提供实现类

我们这里提供了接口的2个实现类。

package com.lm.service.impl;

import com.lm.service.IService;

/**
 * @author Liu.Liangyuan
 * @version $Id: CatService.java, v 0.1 2022年04月10日 8:36 下午 LiangMu Exp $$
 */
public class CatService implements IService {
    @Override
    public void sayHello() {
        System.out.println("cat hello");
    }
}
package com.lm.service.impl;

import com.lm.service.IService;

/**
 * @author Liu.Liangyuan
 * @version $Id: DogService.java, v 0.1 2022年04月10日 8:35 下午 LiangMu Exp $$
 */
public class DogService implements IService {
    @Override
    public void sayHello() {
        System.out.println("dog hello");
    }
}

3. 提供ServiceLoader配置

4. 调用ServiceLoader来加载接口服务

package com.lm;

import com.lm.service.IService;

import java.util.ServiceLoader;

/**
 * @author Liu.Liangyuan
 * @version $Id: Main.java, v 0.1 2022年04月10日 8:38 下午 LiangMu Exp $$
 */
public class Main {
    public static void main(String[] args) {
        ServiceLoader<IService> serviceLoader = ServiceLoader.load(IService.class);
        for (IService service : serviceLoader) {
            service.sayHello();
        }
    }
}

DEBUG

RUN RESULT


Spring框架也提供了SPI的实现方式,这里不赘述,有兴趣的直接百度。

猜你喜欢

转载自blog.csdn.net/qq_44503987/article/details/124085718