0Pricing
Java Academy · Lezione

Servizi con provides/uses

Disaccoppiare con il service loader

Servizi con provides/uses è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 3 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.

Disaccoppiare con i servizi

I moduli possono collaborare senza dipendere dalle rispettive implementazioni usando il pattern del service loader.

Un modulo dichiara di usare un'interfaccia di servizio con uses; un altro dichiara di fornire un'implementazione con provides. La JVM li collega.

I tre ruoli

Un servizio ha tre partecipanti:

  • Interfaccia del servizio: il contratto, definito in un modulo
  • Provider: un modulo che fornisce un'implementazione
  • Consumer: un modulo che carica le implementazioni a runtime

L'interfaccia del servizio

Per prima cosa definisca il contratto. È una normale interfaccia in un package esportato, così provider e consumer possono farvi riferimento.

package com.example.spi;

public interface Codec {
    String name();
    byte[] encode(String input);
}

Il consumer dichiara uses

Il modulo consumer dichiara di usare l'interfaccia con uses. Questo comunica a JPMS che il modulo cercherà le implementazioni tramite ServiceLoader.

module com.example.app {
    requires com.example.spi;
    uses com.example.spi.Codec;
}

Il provider dichiara provides

Un modulo provider dichiara quale interfaccia implementa con provides ... with ..., specificando la sua classe concreta.

module com.example.base64 {
    requires com.example.spi;
    provides com.example.spi.Codec
        with com.example.base64.Base64Codec;
}

L'implementazione del provider

La classe di implementazione è una normale classe Java. Deve essere pubblica e avere un costruttore pubblico senza argomenti oppure un metodo statico pubblico provider().

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());
    }
}

Caricare con ServiceLoader

A runtime, il consumer chiede a ServiceLoader.load(Codec.class) tutti i provider disponibili e li itera, senza alcun collegamento in fase di compilazione con un'implementazione.

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());
        }
    }
}

Perché è potente

Il consumer non nomina mai una classe provider. Aggiunga un nuovo modulo provider al module path e verrà rilevato automaticamente.

Questo consente architetture a plugin e un'inversione pulita delle dipendenze.

La factory provider()

Se la costruzione richiede della logica, esponga un metodo statico pubblico provider() invece di un costruttore senza argomenti. JPMS lo chiama per ottenere l'istanza.

package com.example.base64;

import com.example.spi.Codec;

public class CodecFactory {
    public static Codec provider() {
        return new Base64Codec();
    }
}

Più provider

Molti moduli possono fornire la stessa interfaccia. ServiceLoader li restituisce tutti, consentendo al consumer di scegliere in base al nome, alla priorità o alle funzionalità.

Aggiunga o rimuova provider senza modificare il codice del consumer.

Stream dei provider

A partire da Java 9, ServiceLoader offre stream(), restituendo handle Provider che è possibile filtrare prima di istanziarli, utile quando la costruzione è costosa.

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());
    }
}

Verifica rapida

Ricordi quale direttiva usa ciascun ruolo.

Riepilogo

Ha appreso il pattern dei servizi dei moduli:

  • Tre ruoli: interfaccia del servizio, provider, consumer
  • Consumer: uses; provider: provides ... with
  • Implementazioni caricate a runtime tramite ServiceLoader
  • I provider richiedono un costruttore pubblico senza argomenti oppure un metodo statico provider()

Successivo: migrare un progetto esistente ai moduli.

Domande Frequenti

La lezione «Servizi con provides/uses» è gratuita?

Sì — il testo completo di «Servizi con provides/uses» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.

Cosa imparerò in «Servizi con provides/uses»?

Disaccoppiare con il service loader Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Java Academy?

Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 3 di 4.

Quanto tempo richiede la lezione «Servizi con provides/uses»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Java Academy?

Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. module-info.java
  2. requires e exports
  3. Servizi con provides/uses
  4. Migrazione ai moduli
← Torna a Java Academy