Java SPI и демонстрация

Java
Прежде всего, чтобы объяснить предысторию, что такое Java SPI?

Полное название SPI (Service Provider Interface) — это механизм обнаружения поставщиков услуг, встроенный в JDK.

Зачем нужен СПИ? 

     Наши современные системы становятся все больше и больше. Если есть проблема с архитектурой дизайна, это может повлиять на все тело. В объектно-ориентированном программировании мы рекомендуем программирование на основе интерфейса и программирование на основе интерфейса между модулями. Преимущества этого очевидны, а не в коде.Жестко запрограммированные, разные реализаторы реализуют свои внутренние операции в соответствии со спецификацией интерфейса, а затем при его использовании получают реализацию службы соответствующего поставщика услуг в соответствии со спецификацией SPI. Регистрация и обнаружение служб с помощью механизма загрузки служб SPI может эффективно избежать записи поставщика служб в программный код. Таким образом, разделение между модулями может быть реализовано на основе программирования интерфейса.

Соглашение о механизме SPI:

1. Создайте файл с полным именем интерфейса в каталоге META-INF/services/.Содержимое файла представляет собой полное имя конкретного класса реализации API.

2. Используйте класс ServiceLoader для динамической загрузки класса реализации в META-INF.

3. Если классом реализации SPI является Jar, его необходимо поместить в основную программу ClassPath.  

4. Конкретный класс реализации API должен иметь конструктор без параметров  

Как показано на рисунке:


Кейсы, которые использовались сейчас: 

  • common-loging Фасадный интерфейс самого раннего журнала, предоставленного Apache. Есть только интерфейсы, никаких реализаций. Конкретная схема реализуется каждым поставщиком.Провайдер журнала находится путем сканирования файла конфигурации META-INF/services/org.apache.commons.logging.LogFactory и чтения содержимого файла, чтобы найти класс реализации поставщика журнала. . Пока этот файл включен в нашу реализацию журнала, и класс реализации интерфейса фабрики LogFactory сформулирован в файле. 
  • До JDBC jdbc4.0 разработчикам также необходимо было загружать драйверы на основе Class.forName("xxx"). Создайте соединение: в DriverManage.getConnection() есть Connection con = aDriver.driver.connect(url, info); Переменная-член драйвера — это интерфейс java.sql.Driver, загрузочный интерфейс драйвера, предоставляемый Java, который Java не реализован. Что касается реализации этого интерфейса, то он реализован различными производителями JDBC. Например, MySQL, есть файл java.sql.Driver в пакете META-INF.services в пакете mysql-connector-java-5.1.38.jar.Откройте файл и найдите следующие две строки: com.mysql. jdbc.Driver com.mysql.fabric.jdbc.FabricMySQLDriver

Пример демонстрации:

  1. Создать maven-проект
  2. Каталог выглядит следующим образом:
      


  3. код
    OrderService.java

    package com.demo.spi.service;
    
    public interface OrderService {
        int getOrderCountById(int id);
    }
    

      CustomerOrderServiceImpl.java

package com.demo.spi.impl;

import com.demo.spi.service.OrderService;

public class CustomerOrderServiceImpl implements OrderService {

    public int getOrderCountById(int id) {
        System.out.println("cutomer order count is 10");
        return 10;
    }

}

       AgencyOrderServiceImpl.java

package com.demo.spi.impl;

import com.demo.spi.service.OrderService;

public class AgencyOrderServiceImpl implements OrderService {

    public int getOrderCountById(int id) {
        System.out.println("agency order count is 20");
        return 20;
    }

}

Имя файла в META-INF: com.demo.spi.service.OrderService, содержимое файла:

com.demo.spi.impl.AgencyOrderServiceImpl
com.demo.spi.impl.CustomerOrderServiceImpl

4. Создайте новый тестовый проект Java-проекта.



Адрес кода на github: https://github.com/HuoMoreMore/demo-spi

Прежде чем запускать основной метод, нам нужно упаковать jar первого проекта, чтобы он зависел от второго java-проекта.Нажмите «Выполнить» после завершения, и вы увидите, что вывод двух методов serviceImpl в проекте 1 распечатывается. скажем, ServiceLoader динамически находит класс реализации в проекте 1 через конфигурацию в банке и записывает его в память, мы можем напрямую вызывать два класса реализации, предоставленных в проекте 1, и выводить правильно.

Если есть необходимость понять источник, друзья ServiceLoader могут обратиться к:

https://www.jianshu.com/p/a6073e9f8cb4