Die Implementierung eines Java SPI ist nicht gerade ein Erlebnis des Jahres 20111. Eine Textdatei mit dem richtigen Namen in META-INF/services zu erstellen, dafür zu sorgen, dass sie korrekt verpackt ist, und daran zu denken, sie auf dem neuesten Stand zu halten, wenn Sie ein Refactoring vornehmen, ist so lästig und fehleranfällig, dass es zumindest ein
Was ist mit ServiceLoader?
Offensichtlich haben die Ingenieure von SunOracle- als prominente SPI-Konsumenten - diese Frustration geteilt. In Java 6 führten sie ServiceLoader ein, um zumindest die Nutzung von "Vanilla" SPI zu vereinfachen. MultiSPI ist jedoch nicht nur eine vollständig kompatible Alternative für diejenigen, die noch mit Java 5 arbeiten. Es unterstützt auch eine Reihe gängiger zusätzlicher Anwendungsfälle:
- Überprüfung der Liste der Klassennamen, bevor sie geladen werden, z.B. um einige Elemente zu entfernen oder zu ersetzen (z.B. benutzerdefinierte Überschreibungen), um verschiedene Klassenlader für verschiedene Pakete zu verwenden (z.B. OSGi) usw.
- Inspektion der Klassen vor ihrer Instanziierung, z. B. um zu prüfen, ob Annotationen oder implementierte Schnittstellen erforderlich sind, um die Erstellung von Instanzen zu verzögern usw.
- Verwendung von Nicht-Vanilla-Instanzierungsstrategien, zum Beispiel zur Unterstützung von Factory-Methoden oder in Verbindung mit Dependency Injection usw.
Erbringung von Dienstleistungen 2011
Noch wichtiger ist jedoch, dass MultiSPI nicht nur das Lesen von Service-Implementierungen aus META-INF/Services-Dateien unterstützt. Denn seien wir ehrlich, wenn Sie heute einen Komponenten-Provider-Mechanismus entwerfen, wird dieser wahrscheinlich nicht auf der
SPIs und Injektion von Abhängigkeiten
Letztendlich sind SPIs natürlich nur Service-Fabriken, und wenn Sie in einem Dependency-Injection-Kontext arbeiten, wollen Sie wahrscheinlich nicht explizit einen SPI-Loader aufrufen, sondern nur, dass die resultierenden Services für die Injektion in Ihre Geschäftslogik "verfügbar" sind. In der Tat hat Spring in Version 2.5 eine ServiceLoader-gestützte Fabrik hinzugefügt, und natürlich können Sie dasselbe mit MultiSPI tun, egal ob Sie die Namen der Implementierungsklassen, die Klassen oder die Instanzen selbst wollen. Es gibt Beispiele für Spring und Guice. Hier ist zum Beispiel der Spring-Kontext, der eine Reihe von Klassennamen, Klassen und Instanzen vorbereitet:
[xml]
<bean id="multiSpi" class="com.qrmedia.commons.multispi.MultiSpi">
<constructor-arg>
<set>
<bean class="com.qrmedia.commons.multispi.provider.MetaInfServicesProvider" />
<bean class="com.qrmedia.commons.multispi.provider.AnnotationScanningProvider">
<constructor-arg value="uk.gov.mi6.LicenseToKill" />
<constructor-arg value="uk.gov" />
</bean>
</set>
</constructor-arg>
</bean>
<bean id="agentNames" factory-bean="multiSpi" factory-method="findImplementationNames">
<constructor-arg value="uk.gov.mi6.Agent" />
</bean>
<bean id="agentClasses" factory-bean="multiSpi" factory-method="findImplementations">
<constructor-arg value="uk.gov.mi6.Agent" />
</bean>
<bean id="agents" factory-bean="multiSpi" factory-method="loadImplementations">
<constructor-arg value="uk.gov.mi6.Agent" />
</bean>
[/xml]
Natürlich können Sie viele verschiedene MultiSpi-Instanzen mit unterschiedlichen Provider-Konfigurationen gleichzeitig in Ihrer Anwendung verwenden.
MultiSPI verwenden
Um MultiSPI zu verwenden, fügen Sie einfach die folgenden Abhängigkeiten und Repositories zu Ihrem POM hinzu:
[xml]
<dependency>
<groupId>com.qrmedia.commons</groupId>
<artifactId>multi-spi</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<repository>
<id>qrmedia-releases</id>
<url> https://aphillips.googlecode.com/svn/maven-repository/releases </url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>qrmedia-snapshots</id>
<url> https://aphillips.googlecode.com/svn/maven-repository/snapshots </url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
[/xml]
Wenn Sie glauben, dass Sie auf widersprüchliche Abhängigkeiten stoßen könnten und etwas wollen, das einfach funktioniert, ohne sich mit <excludes> auseinandersetzen zu müssen, können Sie verwenden:
[xml]
<dependency>
<groupId>com.qrmedia.commons</groupId>
<artifactId>multi-spi</artifactId>
<version>1.0-SNAPSHOT</version>
<classifier>jar-with-dependencies</classifier>
</dependency>
[/xml]
statt. Die Maven-Site und die Projektberichte finden Sie unter aphillips.googlecode.com/svn/maven-sites/multi-spi/1.0-SNAPSHOT/project-info.html.
Verfasst von
Andrew Phillips
Unsere Ideen
Weitere Blogs
Contact



