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