Полное название 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
Пример демонстрации:
- Создать maven-проект
- Каталог выглядит следующим образом:
-
код
OrderService.javapackage 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