What is the mechanism of the JDK SPI

What is SPI and API

 Application Programming Interface (API)?

  • The API is the description of classes/interfaces/methods/... that you call and use to achieve a goal, and

  • the SPI is the description of classes/interfaces/methods/... that you extend and implement to achieve a goal.

The full name of SPI (Service Provider Interface), is the built-in JDK provides a service discovery mechanism. SPI is a dynamic alternative mechanism found, for example, there is the interface, add it to achieve dynamic want to run, you just need to add a realization. We often encounter is java.sql.Driver interfaces, various other vendors can make different implementations for the same interface, mysql, postgresql have different implementations available to the user, while the Java service for SPI mechanism may find an interface achieve.

First, put a figure: between us, "caller" and "to achieve party" need to introduce the "interface", you can think about what the caller should be put into the interface, when the interface can be classified as implementer.

Let's look at the interface belongs to the party of the situation to realize, this is very easy to understand, implement provided by the interface and implementation, we can refer to the interface implementation class to achieve a certain function calls, this is what we often say api, it has the following characteristics:

  1. Is a description of implementation (what I can offer to you)

  2. Located on the organization achieve square where the package

  3. And an interface implemented in a package

When the interface belong to the caller, let's call spi, full name: service provider interface, spi rules are as follows:

  1. Is bound to achieve (To provide this functionality, implementers need to do those things)

  2. Organizational package is located in the caller's location

  3. Implemented in a separate package (it can also be considered in providing prescription)

in short

API will tell you specific class / method you what to do, while the SPI tell you what must be done to meet the requirements. Typically, API, and SPI are separated. For example, in JDBC, Driver class is part of the SPI: If you want to use the JDBC, there is no need to use it directly, but to achieve each JDBC driver class must implement. However, sometimes they overlap. Connection interface both SPI, but also API: you would normally use it when you use the JDBC driver, and needs to be implemented by the developer JDBC driver.

 

JDK

In jdk6 which introduced a new feature ServiceLoader, from the official documents, it is mainly used to load a series of service provider. ServiceLoader can be loaded and designated by the service provider's service provider profile. When service providers, provides an implementation of the service interface After that, we just need to create a service interface to the file named META-INF jar package / services / directory. The document is the realization of the service implementation class interface. And when the external program module assembly, to find a specific category by the name of the jar package META-INF / services / in the configuration file loading instantiates and complete injection module. Above may speak somewhat abstract, the following specific examples to talk about a combination.

public interface Search {
  public List<String> searchDoc(String keyword);  
}

File search implementation

public class FileSearch implements Search{
  @Override
  public List<String> searchDoc(String keyword) {
      System.out.println("文件搜索 "+keyword);
      return null;
  }
}

Database search implementation

public class DatabaseSearch implements Search{
  @Override
  public List<String> searchDoc(String keyword) {
      System.out.println("数据搜索 "+keyword);
      return null;
  }
}

Then you can create a new META-INF / services / directory in the resources, and create a new interface to the fully qualified name of the file: com.cainiao.ys.spi.learn.Search, which together with the implementation class we need to use

com.github.spi.learn.FileSearch

test

public class TestCase {
  public static void main(String[] args) {
      ServiceLoader<Search> s = ServiceLoader.load(Search.class);
      Iterator<Search> iterator = s.iterator();
      while (iterator.hasNext()) {
          Search search = iterator.next();
          search.searchDoc("hello world");
      }
  }
}

You can see the output: hello world file search

If you write two in com.github.spi.learn.Search implementation class file, the result is that the final output of the two lines. This is because ServiceLoader.load (Search.class) when loading an interface, will go to find the fully qualified name of the interface file at META-INF / services, and then load the appropriate class implemented according to the contents inside.

This is spi ideas, implementation of the interface implemented by the provider, provider only in the jar package submitted by the META-INF / services platform based on the interface definition of the new file, and add content into the corresponding implementation class is like.

Why profile Why put META-INF / services below? You can open ServiceLoader code, which defines the files PREFIX follows:

private static final String PREFIX = "META-INF/services/"

Java SPI is very simple to use. Also do basic function of load extension points. But Java SPI has the following disadvantages:

  • We need to traverse all implementations, and instantiate before we can find what we need to achieve in the cycle.

  • Configuration file simply lists all the extensions to achieve, but did not give them a name. Cause they are difficult to accurately quoted in the program.

  • If the other extended-dependent extension, and can not automatic injection assembly

  • Spring does not provide a similar function of IOC and AOP

  • Extended difficult to integrate with other frameworks, such as the expansion which depend on a Spring bean, native Java SPI does not support

Guess you like

Origin www.cnblogs.com/munan56/p/12220623.html