JAVA之SPI机制的使用姿势~

本文详细介绍如何使用Java SPI机制实现实时模块加载,通过定义接口、实现类和管理类,实现不同功能模块的动态加载与解耦。通过具体实例,展示了如何根据不同动物类型加载相应处理逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常看到各种开源框架,支持各种模块自定义组合使用,比如先引入主模块,然后引入A模块就具有A功能,引入B就有B功能~

如果使用的是spring则他们使用spring动态注入的方式实现解耦功能模块,我们现在使用spi自己实现一下类似功能~

一.定义接口类:

1.定义接口(所有实现方法都来自该接口):

public interface AnimalService {
    void process(Animal animal);
}

2.定义实体:

public class Animal {
    private String name;
    public Animal(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

3.定义管理类:

public class AnimalManager {

    private final static Set<AnimalService> set = new HashSet<AnimalService>();

    static {
        init();
    }

    private static void init() {
        ServiceLoader<AnimalService> load = ServiceLoader.load(AnimalService.class);
        Iterator<AnimalService> iterator = load.iterator();
        while (iterator.hasNext()) {
            iterator.next();
        }
    }

    public static void regist(AnimalService animalService) {
        set.add(animalService);
    }

    public static void process(Animal animal) {
        for (AnimalService s : set) {
            s.process(animal);
        }
    }
}

二.定义实现类:

1.定义实现接口类:

public class CatServiceImpl implements AnimalService {

    static {
        AnimalManager.regist(new CatServiceImpl());
    }

    @Override
    public void process(Animal animal) {
        if (animal.getName().equalsIgnoreCase("cat")) {
            System.out.println("喵喵~");
        }
    }
}

2.定义spi文件:

resources下新建    META-INF/services/com.kakuiwong.service.AnimalService
内容为        com.kakuiwong.CatServiceImpl

三.定义另一个实现类:

public class DogServiceImpl implements AnimalService {

    static {
        AnimalManager.regist(new DogServiceImpl());
    }

    @Override
    public void process(Animal animal) {
        if (animal.getName().equalsIgnoreCase("dog")) {
            System.out.println("汪汪~");
        }
    }
}


resources下新建同样文件,内容为com.kakuiwong.DogServiceImpl

四.测试:

1.引入以上三个依赖:

  <dependencies>
        <dependency>
            <groupId>com.kakuiwong</groupId>
            <artifactId>api-service</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.kakuiwong</groupId>
            <artifactId>cat</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.kakuiwong</groupId>
            <artifactId>dog</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

2.测试功能:

public class Main {

    public static void main(String[] args) {
        Animal cat = new Animal("cat");
        Animal dog = new Animal("dog");
        AnimalManager.process(cat);
        AnimalManager.process(dog);
    }
}

打印结果:
喵喵~
汪汪~

如果将dog依赖去掉,则只会打印喵喵~引入相关依赖则引入其功能;

 

五.总结:

其中关键代码是这个类ServiceLoader,用来动态加载META-INF/services下的实现类;

ServiceLoader.load(AnimalService.class);

然后迭代所有实现类,此时会进行初始化;

Iterator<AnimalService> iterator = load.iterator();
while (iterator.hasNext()) {
    iterator.next();
}

初始化时会首先调用static{}静态代码块里的代码,基础呦~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值