java-spi机制用于实现java程序的插件解耦,通过定义接口的方式实现程序和插件的关联。
具体的实现,需要先定义一个接口,主程序使用这个接口调用插件中的实现类,插件通过实现这个接口完成功能开发和被调用。
插件需要在META-INF中配置实现了哪个接口类和具体实现类的包名和类名。

插件中META-INF配置文件
路径: /META-INF/services/接口的完整限定名
内容:本插件中该接口实现类的完整限定名(每行写一个实现类 可以多个)

主程序读取该实现类方法(Gen为接口类)

   ServiceLoader serviceLoader = ServiceLoader.load(Gen.class);

举个栗子:

创建1个maven项目: java-spi,包含子模块: main,plugin

2个子模块中新增接口:
此为程序和插件交互的桥梁

package cn.coderstory.plugin;

public interface Gen {
    String gen();
}

plugin模块实现该接口:

package cn.coderstory.impl;

public class Gen  implements cn.coderstory.plugin.Gen {

    public String gen() {
        return "gen";
    }
}

plugin模块新增配置文件: src/main/resources/META-INF/services/cn.coderstory.plugin.Gen
内容为: cn.coderstory.impl.Gen
pom文件新增配置:

    
    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
            
            
            
                org.apache.maven.plugins
                maven-jar-plugin
                
                    
                        false
                    
                
            

        
    

主程序读取所有的插件中的实现类

    
package cn.coderstory.plugin;

import java.util.Iterator;
import java.util.ServiceLoader;

public class Main {
    public static void main(String[] args) {
        ServiceLoader serviceLoader = ServiceLoader.load(Gen.class);
        Iterator iterator = serviceLoader.iterator();
        while(iterator.hasNext()){
            Gen generator = iterator.next();
            String id = generator.gen();
            System.out.println(generator.getClass().getName() + "  >>id:" + id);
        }
    }
}

日志输出:
已连接到目标 VM, 地址: ''127.0.0.1:50713',传输: '套接字''
cn.coderstory.impl.Gen >>id:gen
与目标 VM 断开连接, 地址为: ''127.0.0.1:50713',传输: '套接字''

进程已结束,退出代码为 0

届ける言葉を今は育ててる
最后更新于 2024-02-01