SPI用法簡介

spi是Service Provider Interface的縮寫。使用spi技術能夠經過修改配置的方式,更換程序中某個接口的實現類,從而改變程序行爲。spi的用法以下:html

  1. 定義接口。
package com.foo.bar.service;
public interface Foo {
    String foo(String name);
}
  1. 編寫接口實現類。
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);
    }
}
  1. 創建spi文件。

創建文件META-INF\services\com.foo.bar.service.FooService,寫入下面兩行:java

com.foo.bar.provider.v1.FooServiceProvider
com.foo.bar.provider.v2.FooServiceProvider
  1. 加載接口實現類。
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");
  }
}
  1. 在Spring中使用spi。
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;
  }
}
  1. 對JDBC使用spi。

編輯文件META-INF/services/java.sql.Driver,加入所須要的驅動類。spring

參考資料sql

相關文章
相關標籤/搜索