spi is the abbreviation of Service Provider Interface. Using spi technology, we can change the implementation class of an interface in a program by modifying the configuration, so as to change the program behavior. The usage of spi is as follows:
- Define the interface.
package com.foo.bar.service; public interface Foo { String foo(String name); }
- Write the interface implementation class.
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); } }
- Establish the spi file.
Create a file META-INF\services\com.foo.bar.service.FooService and write the following two lines:
com.foo.bar.provider.v1.FooServiceProvider com.foo.bar.provider.v2.FooServiceProvider
- Load the interface implementation class.
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"); } }
- Use spi in Spring.
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; } }
- Use spi for JDBC.
Edit the file META-INF/services/java.sql.Driver to add the required driver class.
Reference material