spi是Service Provider Interface的缩写。使用spi技术能够经过修改配置的方式,更换程序中某个接口的实现类,从而改变程序行为。spi的用法以下:html
package com.foo.bar.service; public interface Foo { String foo(String name); }
package com.foo.provider.v1; public class FooServiceProvider implements Foo { String foo(String name) { return "hello" + name; } } package com.foo.provider.v2; public class FooServiceProvider implements Foo { String foo(String name) { return String.format("Hello, %s!", name); } }
创建文件META-INF\services\com.foo.bar.service.FooService,写入下面两行:java
com.foo.bar.provider.v1.FooServiceProvider com.foo.bar.provider.v2.FooServiceProvider
import java.util.ServiceLoader; import com.foo.bar.service.FooService; public class App { public static void main(String[] args) { for (FooService provider: ServiceLoader.load(FooService.class)) { System.out.println(provider.foo("Foo"); } }
public interface BarService { public String bar(String abc); } public class BarServiceProvider { public String bar(String abc) { return ""; } } public class Demo { private static ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfiguration.class); public static void main(String[] args) { BarService dictionary = ctx.getBean(BarService.class); System.out.println("Book: " + dictionary.bar("book")); } } @Configuration public class AppConfiguration { @Bean public BarService barService(ServiceLoader<Service> loader) { return new Service(loader); } @Bean public ServiceLoaderFactoryBean dictionaryServiceLoaderFactory() { ServiceLoaderFactoryBean factoryBean = new ServiceLoaderFactoryBean(); factoryBean.setServiceType(BarService.class); return factoryBean; } }
编辑文件META-INF/services/java.sql.Driver,加入所须要的驱动类。spring
参考资料sql