配套视频:https://cloud.tencent.com/developer/video/76588

SPI(Service Provider Interface)是一种服务发现机制,它通过在类路径下的META-INF/services目录下的配置文件来发现服务实现类,实现了面向接口编程的扩展性。 Java SPI是JDK自带的一种SPI机制,它通过在META-INF/services目录下的配置文件中指定接口的实现类来实现。Java SPI只能加载到类路径下的实现类,不支持动态添加和删除实现类。Java SPI的实现代码示例如下: 定义接口 public interface MyService { void doSomething(); } 实现接口 public class MyServiceImpl implements MyService { @Override public void doSomething() { System.out.println("do something by MyServiceImpl"); } } 配置文件 在META-INF/services目录下创建一个以接口全限定名为文件名的文件,并在文件中指定实现类的全限定名。 com.example.MyService com.example.MyServiceImpl 加载实现类 public class Main { public static void main(String[] args) { ServiceLoader<MyService> loader = ServiceLoader.load(MyService.class); for (MyService service : loader) { service.doSomething(); } } } Dubbo SPI是Apache Dubbo框架自带的一种SPI机制,它在Java SPI基础上进行了扩展,支持动态添加和删除实现类。Dubbo SPI的实现代码示例如下: 定义接口 @SPI("default") public interface MyService { void doSomething(); } 实现接口 @SPI("impl1") public class MyServiceImpl1 implements MyService { @Override public void doSomething() { System.out.println("do something by MyServiceImpl1"); } }

@SPI("impl2") public class MyServiceImpl2 implements MyService { @Override public void doSomething() { System.out.println("do something by MyServiceImpl2"); } } 配置文件 在META-INF/dubbo目录下创建一个以接口全限定名为文件名的文件,并在文件中指定实现类的名称和对应的扩展名。

META-INF/dubbo/com.example.MyService

impl1=com.example.MyServiceImpl1 impl2=com.example.MyServiceImpl2 加载实现类 public class Main { public static void main(String[] args) { ExtensionLoader<MyService> loader = ExtensionLoader.getExtensionLoader(MyService.class); MyService service = loader.getExtension("impl1"); service.doSomething(); } } Spring SPI是Spring框架自带的一种SPI机制,它通过在META-INF/spring.factories文件中指定实现类来实现。Spring SPI的实现代码示例如下: 定义接口 public interface MyService { void doSomething(); } 实现接口 public class MyServiceImpl implements MyService { @Override public void doSomething() { System.out.println("do something by MyServiceImpl"); } } 配置文件 在META-INF/spring.factories文件中指定实现类的全限定名。 com.example.MyService=com.example.MyServiceImpl 加载实现类 public class Main { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(); MyService service = context.getBean(MyService.class); service.doSomething(); } }