框架必备的SPI扩展机制

2019-05-09  本文已影响0人  十毛tenmao

很多框架中,为了实现更好的扩展机制,都是用了JDK支持的SPI机制,本文简单介绍了一下,并提供了快速实现的示例

SPI

Java SPI(Service Provider Interface)是一种JDK支持的扩展机制,可以为某个接口寻找服务实现的机制,有点类似于IOC的思想,将装配的控制权移到了程序之外。


Java SPI

SPI常用场景

MySQL Driver

接口定义方

类似于JDK中的java.sql.Driver

public interface Scorer {
    double score(String first, String second);
}
public class ScorerManager {
    private static final Map<String, Scorer> SCORER_MAP = new HashMap<>(16);

    static {
        loadInitialScorers();
        System.out.println("Scorer Manager initialized");
    }

    public static void registerScore(Scorer scorer) {
        SCORER_MAP.putIfAbsent(scorer.getClass().getName(), scorer);
    }

    public static Scorer getScore(String scoreName) {
        Scorer scorer = SCORER_MAP.get(scoreName);
        if (scorer == null) {
            throw new RuntimeException("cannot not find score with name:" + scoreName);
        }
        return scorer;
    }

    private static void loadInitialScorers() {
        ServiceLoader<Scorer> serviceLoader = ServiceLoader.load(Scorer.class);
        for (Scorer scorer : serviceLoader) {
            //这里可以什么都不做,只是出发实现类的构造函数和静态模块
            //其实也可以在这里完成注册,这样的话各个实现类会更加简单。不过在实现类中实现注册,会更加灵活,因为实现类在注册之前也许还需要做一些初始化的工作
        }
    }
}

接口实现方

类似于mysql中的com.mysq.Drivercom.mysql.cj.jdbc.Driver, h2中的org.h2.Driver

public class BarScorer implements Scorer {
    static {
        ScorerManager.registerScore(new BarScorer());
        System.out.println("BarScorer initialized");
    }

    @Override
    public double score(String first, String second) {
        return 0;
    }
}
com.tenmao.BarScorer

接口使用方

public static void main(String[] args) {
    Scorer score = ScorerManager.getScore("com.tenmao.BarScorer");
    double scoreOne = score.score("1", "1");
    System.out.println(scoreOne);
}

注意事项

参考

上一篇下一篇

猜你喜欢

热点阅读