dubbo采用微内核+插件体系,设计优雅,扩展性很强。微内核+插件体系是如何实现的呢?想必大家都知道SPI(service provider interface)机制。这种机制的原理是假如我们定义了服务接口标准,可以让厂商无实现。在jdk中,使用ServiceLoader类来实现spi机制的服务查找功能。
接下来我们使用一个简单的例子,通过ServiceLoader来实现spi机制。先定义一个接口:
package com.ysl; public interface Spi { boolean isSupportType(String type); String sayGoodBy(); }
ServiceLoader会遍历所有的jar去查找META-INF/services/com.ysl.Spi文件
假设A厂商提供的实现如下:
package com.ysl; public class SpiAImpl implements Spi{ @Override public boolean isSupportType(String type) { return "A".equals(type); } @Override public String sayGoodBy() { return "bye bye A"; } }
在A厂商提供的jar包中的META-INF/services/com.ysl.Spi文件内容为:com.ysl.SpiAImpl(厂商A的spi实现全路径类名)
假设B厂商提供的实现如下:
package com.ysl; public class SpiBImpl implements Spi{ @Override public boolean isSupportType(String type) { return "B".equals(type); } @Override public String sayGoodBy() { return "bye bye B"; } }
在B厂商提供的jar包中的META-INF/services/com.ysl.Spi文件内容为:com.ysl.SpiBImpl(厂商B的spi实现全路径类名)
ServiceLoader.load(Spi.class)读取厂商A、B提供jar包中的文件,ServiceLoader实现了Iterable接口可通过while for循环语句遍历出所有实现。
一个接口多种实现,就如策略模式一样提供了策略的实现,但是没有提供策略的选择, 使用方可以根据isSupport方法根据业务传入厂商名来选择具体的厂商。
package com.ysl; import java.util.ServiceLoader; public class SpiFactory { private static ServiceLoader spiLoader = ServiceLoader.load(Spi.class); public static Spi getSpi(String name){ for(Spi spi : spiLoader){ if(spi.isSupportType(name)){ return spi; } } return null; } }