Dienste mit provides/uses
Mit dem Service Loader entkoppeln
Dienste mit provides/uses ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Entkopplung mit Services
Module können mithilfe des Service-Loader-Musters zusammenarbeiten, ohne von den Implementierungen der jeweils anderen abhängig zu sein.
Ein Modul deklariert, dass es eine Service-Schnittstelle uses; ein anderes deklariert eine Implementierung mit provides. Die JVM verbindet sie miteinander.
Die drei Rollen
Ein Service hat drei Beteiligte:
- Service-Schnittstelle: der Vertrag in einem Modul
- Provider: ein Modul, das eine Implementierung bereitstellt
- Consumer: ein Modul, das Implementierungen zur Laufzeit lädt
Die Service-Schnittstelle
Zuerst definieren Sie den Vertrag. Es handelt sich um eine normale Schnittstelle in einem exportierten Paket, sodass sowohl Provider als auch Consumer darauf verweisen können.
package com.example.spi;
public interface Codec {
String name();
byte[] encode(String input);
}Der Consumer deklariert uses
Das Consumer-Modul deklariert, dass es die Schnittstelle mit uses verwendet. Dadurch weiß JPMS, dass das Modul Implementierungen über ServiceLoader suchen wird.
module com.example.app {
requires com.example.spi;
uses com.example.spi.Codec;
}Der Provider deklariert provides
Ein Provider-Modul deklariert mit provides ... with ..., welche Schnittstelle es implementiert, und gibt dabei seine konkrete Klasse an.
module com.example.base64 {
requires com.example.spi;
provides com.example.spi.Codec
with com.example.base64.Base64Codec;
}Die Provider-Implementierung
Die Implementierungsklasse ist gewöhnliches Java. Sie muss public sein und entweder einen öffentlichen parameterlosen Konstruktor oder eine öffentliche statische provider()-Methode besitzen.
package com.example.base64;
import com.example.spi.Codec;
import java.util.Base64;
public class Base64Codec implements Codec {
public String name() { return "base64"; }
public byte[] encode(String input) {
return Base64.getEncoder().encode(input.getBytes());
}
}Laden mit ServiceLoader
Zur Laufzeit fordert der Consumer mit ServiceLoader.load(Codec.class) alle verfügbaren Provider an und durchläuft sie, ohne dass zur Kompilierungszeit eine Verbindung zu einer Implementierung besteht.
import com.example.spi.Codec;
import java.util.ServiceLoader;
public class App {
public static void main(String[] args) {
ServiceLoader<Codec> loader = ServiceLoader.load(Codec.class);
for (Codec codec : loader) {
System.out.println("Found codec: " + codec.name());
}
}
}Warum das so leistungsfähig ist
Der Consumer benennt niemals eine Provider-Klasse. Legen Sie ein neues Provider-Modul auf den Modulpfad, wird es automatisch erkannt.
So werden Plugin-Architekturen und eine saubere Umkehrung von Abhängigkeiten ermöglicht.
Die provider()-Factory
Wenn die Erstellung Logik erfordert, stellen Sie statt eines parameterlosen Konstruktors eine öffentliche statische provider()-Methode bereit. JPMS ruft sie auf, um die Instanz zu erhalten.
package com.example.base64;
import com.example.spi.Codec;
public class CodecFactory {
public static Codec provider() {
return new Base64Codec();
}
}Mehrere Provider
Viele Module können jeweils dieselbe Schnittstelle bereitstellen. ServiceLoader liefert sie alle zurück, sodass Ihr Consumer anhand von Namen, Priorität oder Fähigkeiten auswählen kann.
Sie können Provider hinzufügen oder entfernen, ohne den Consumer-Code anzupassen.
Stream über Provider
Seit Java 9 bietet ServiceLoader stream() an, das Provider-Handles liefert, die Sie vor der Instanziierung filtern können – nützlich, wenn die Erstellung aufwendig ist.
import com.example.spi.Codec;
import java.util.ServiceLoader;
public class App {
public static void main(String[] args) {
Codec chosen = ServiceLoader.load(Codec.class).stream()
.map(ServiceLoader.Provider::get)
.filter(c -> c.name().equals("base64"))
.findFirst()
.orElseThrow();
System.out.println("Using: " + chosen.name());
}
}Kurze Überprüfung
Rufen Sie sich in Erinnerung, welche Direktive jede Rolle verwendet.
Zusammenfassung
Sie haben das Modul-Service-Muster gelernt:
- Drei Rollen: Service-Schnittstelle, Provider, Consumer
- Consumer:
uses; Provider:provides ... with - Implementierungen werden zur Laufzeit über
ServiceLoadergeladen - Provider benötigen einen öffentlichen parameterlosen Konstruktor oder eine statische
provider()-Methode
Als Nächstes: Ein bestehendes Projekt auf Module umstellen.
Häufig gestellte Fragen
Ist die Lektion „Dienste mit provides/uses“ kostenlos?
Ja — der vollständige Text von „Dienste mit provides/uses“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Dienste mit provides/uses“?
Mit dem Service Loader entkoppeln Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Java Academy zu starten?
Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Dienste mit provides/uses“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?
Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- module-info.java
- requires und exports
- Dienste mit provides/uses
- Auf Module migrieren