Heim >Java >javaLernprogramm >So implementieren Sie den SPI-Mechanismus von SpringBoot
SPI (Service Provider Interface) ist ein in JDK integrierter Service-Discovery-Mechanismus, der zum Aktivieren von Framework-Erweiterungen und Ersatzkomponenten verwendet werden kann. Er wird hauptsächlich für die Entwicklung in Frameworks wie Dubbo, Spring, verwendet. und Common-Logging, JDBC usw. übernehmen den SPI-Mechanismus und verwenden unterschiedliche Implementierungen für dieselbe Schnittstelle, um sie verschiedenen Benutzern bereitzustellen, wodurch die Skalierbarkeit des Frameworks verbessert wird.
Javas integriertes SPI analysiert die Datei mit dem vollständig qualifizierten Namen der Schnittstelle im Verzeichnis META-INF/services/ des Pakets classPath und jar über die Klasse java.util.ServiceLoader und lädt sie Die in der Datei angegebene Schnittstelle. Implementieren Sie die Klasse, um den Aufruf abzuschließen.
public interface VedioSPI { void call(); }
public class Mp3Vedio implements VedioSPI { @Override public void call() { System.out.println("this is mp3 call"); } }
public class Mp4Vedio implements VedioSPI { @Override public void call() { System.out.println("this is mp4 call"); } }
Erstellen Sie ein neues META-INF/services/-Verzeichnis im Quellverzeichnis des Projekts und erstellen Sie com.skywares.fw. juc.spi .VedioSPI-Dateien.
public class VedioSPITest { public static void main(String[] args) { ServiceLoader<VedioSPI> serviceLoader =ServiceLoader.load(VedioSPI.class); serviceLoader.forEach(t->{ t.call(); }); } }
Beschreibung: Java implementiert SPI über ServiceLoader, um die vom Dienst bereitgestellten Toolklassen zu finden.
Das Obige ist nur ein einfaches Beispiel für die Implementierung der in Java integrierten SPI-Funktion. Das Implementierungsprinzip besteht darin, dass ServiceLoader eine integrierte Java-Toolklasse zum Auffinden von Dienstbereitstellungsschnittstellen ist. Sie sucht nach Dienstbereitstellungsschnittstellen, indem sie die Methode „load()“ aufruft und schließlich nacheinander auf die Implementierungsklassen der Dienstbereitstellungsschnittstellen zugreift .
Sie können dem Quellcode entnehmen:
Die ServiceLoader-Klasse selbst implementiert die Iterator-Methode und ruft die Methode nach dem Parsen in der internen Klasse auf Die Schnittstellendatei des Dienstanbieters Das Endergebnis wird im Iterator zurückgegeben, und der direkte Zugriff auf die vom Dienst bereitgestellte Schnittstellenimplementierungsklasse wird nicht unterstützt.
Die entsprechenden Dateien für alle Dienstanbieterschnittstellen werden im Verzeichnis META-INF/services/ abgelegt. Der endgültige Typ bestimmt, dass das PREFIX-Verzeichnis nicht geändert werden kann.
Obwohl die Idee des von Java bereitgestellten SPI-Mechanismus sehr gut ist, hat sie auch entsprechende Nachteile. Die Details lauten wie folgt:
Die in Java integrierten Methoden können nur durch Traversal abgerufen werden.
Die Servicebereitstellungsschnittstelle muss im Verzeichnis META-INF/services/ abgelegt werden.
Angesichts der Probleme, die in Javas SPI bestehen, folgt der SPI-Mechanismus von Spring der Idee von SPI, erweitert und optimiert sie jedoch.
Spring SPI folgt der Designidee von Java SPI Spring verwendet spring.factories, um den SPI-Mechanismus zu implementieren, der die Skalierbarkeit des Spring-Frameworks bereitstellen kann, ohne den Spring-Quellcode zu ändern.
Spring-Beispiel
Definitionsschnittstelle
public interface DataBaseSPI { void getConnection(); }
Zugehörige Implementierung
#DB2实现 public class DB2DataBase implements DataBaseSPI { @Override public void getConnection() { System.out.println("this database is db2"); } } #Mysql实现 public class MysqlDataBase implements DataBaseSPI { @Override public void getConnection() { System.out.println("this is mysql database"); } }
1. Fügen Sie im META-INF-Verzeichnis des Projekts die Datei spring.factories hinzu
2 Geben Sie die relevanten Schnittstelleninformationen ein lautet wie folgt
com.skywares.fw.juc.springspi.DataBaseSPI = com.skywares.fw.juc.springspi.DB2DataBase, com.skywares.fw.juc.springspi.MysqlDataBase
Beschreibung Mehrere Implementierungen werden durch getrennt Kommas.
Verwandte Testklasse
public class SpringSPITest { public static void main(String[] args) { List<DataBaseSPI> dataBaseSPIs =SpringFactoriesLoader.loadFactories(DataBaseSPI.class, Thread.currentThread().getContextClassLoader()); for(DataBaseSPI datBaseSPI:dataBaseSPIs){ datBaseSPI.getConnection(); } } }
Ausgabeergebnisse
Aus dem Beispiel können wir sehen, dass Spring spring.factories zur Implementierung von SPI und Java zur Implementierung von SPI verwendet. Die SPI-Methode von Spring ist jedoch speziell für Javas SPI optimiert Der Inhalt lautet wie folgt:
Java SPI ist eine Dienstbereitstellungsschnittstelle, die einer Konfigurationsdatei entspricht. Die Konfigurationsdatei speichert alle Implementierungsklassen der aktuellen Schnittstelle. Alle Konfigurationen sind in den Diensten enthalten Verzeichnis;
Beschreibung: Rufen Sie den Dateipfad von META-INF/spring.factories in allen JAR-Paketen ab und geben Sie ihn als Aufzählungswert zurück. Durchlaufen Sie den Dateipfad spring.factories, laden und analysieren Sie nacheinander, integrieren Sie den Implementierungsklassennamen des FactoryClass-Typs, rufen Sie den vollständigen Klassennamen der Implementierungsklasse ab und führen Sie dann die Instanzoperation der Klasse aus wie folgt:
Erläuterung: Instanziierung ist Die entsprechende Initialisierung wird durch Reflexion erreicht.
Das obige ist der detaillierte Inhalt vonSo implementieren Sie den SPI-Mechanismus von SpringBoot. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!