SPI (service Provider Interface,是一种面向接口的编程方式。一个接口经常有多个实现类,通过SPI机制发现接口的实现服务。当服务的提供者,需要在META-INF/services下创建接口对应的文件,之后通过java提供的serviceLoader加载对应的实现,并装载实例化。
SPI demo:
package org.dubbo.demo.spi;
/**
* java spi接口。
* @author pc
*
*/
public interface HelloService {
String hello(String name);
}
package org.dubbo.demo.spi.impl;
import org.dubbo.demo.spi.HelloService;
/**
* helloService实现类。
* @author pc
*
*/
public class DefaultHelloService implements HelloService{
@Override
public String hello(String name) {
// TODO Auto-generated method stub
return name +" "+"default";
}
}
package org.dubbo.demo.spi.impl;
import org.dubbo.demo.spi.HelloService;
/**
* HelloService实现类。
* @author pc
*
*/
public class ConsumerHelloService implements HelloService {
@Override
public String hello(String name) {
// TODO Auto-generated method stub
return name + " "+"consumer";
}
}
配置文件。
org.dubbo.demo.spi.impl.DefaultHelloService
org.dubbo.demo.spi.impl.ConsumerHelloService
测试。
package org.dubbo.demo.spi;
import java.util.ServiceLoader;
public class SpiTest {
final ServiceLoader<HelloService> serverLoader = ServiceLoader.load(HelloService.class);
public static void main(String[] args){
SpiTest test =new SpiTest();
ServiceLoader<HelloService> services = test.serverLoader;
for(HelloService service: services){
System.out.println(service.hello("hello"));
}
}
}
java ServiceLoader加载类的不足:
1 , 通过load加载所有的实现类,实现所有的实现类消耗资源。
2 , iterator迭代遍历,不能获取到某个特定的类,加载机制不够灵活。
dubbo扩展了java 的SPI机制。
1 , 添加了获取任意实现类的方法。
2 , 提供了AOP和IOC的支持。
3 , dubbo提供了wrapper自动包装的方式。(装饰者模式)
dubbo规定了放置扩展点配置⽂件 META-INF/dubbo/接⼝全限定名作为SPI的配置文件,类实现配置文件:配置名=扩展实现类全限定名。