0Pricing
Java Academy · Lección

Servicios con provides/uses

Desacople mediante el cargador de servicios

Servicios con provides/uses es una lección gratuita de Java Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Java Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Java Academy incluye 4 lecciones en total.

Desacoplamiento mediante servicios

Los módulos pueden colaborar sin depender de las implementaciones de los demás mediante el patrón de carga de servicios.

Un módulo declara que uses una interfaz de servicio; otro declara que provides una implementación. La JVM los conecta.

Las tres funciones

Un servicio tiene tres participantes:

  • Interfaz de servicio: el contrato, ubicado en algún módulo
  • Proveedor: un módulo que proporciona una implementación
  • Consumidor: un módulo que carga implementaciones en tiempo de ejecución

La interfaz de servicio

Primero debe definir el contrato. Es una interfaz normal en un paquete exportado, de modo que tanto los proveedores como los consumidores puedan hacer referencia a ella.

package com.example.spi;

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

El consumidor declara uses

El módulo consumidor declara que uses la interfaz. Esto indica a JPMS que el módulo buscará implementaciones mediante ServiceLoader.

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

El proveedor declara provides

Un módulo proveedor declara qué interfaz implementa mediante provides ... with ..., indicando el nombre de su clase concreta.

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

La implementación del proveedor

La clase de implementación es Java normal. Debe ser pública y tener un constructor público sin argumentos o un método estático y público 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());
    }
}

Carga con ServiceLoader

En tiempo de ejecución, el consumidor solicita a ServiceLoader.load(Codec.class) todos los proveedores disponibles y los recorre, sin ningún vínculo en tiempo de compilación con una implementación concreta.

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

Por qué es potente

El consumidor nunca menciona la clase del proveedor. Coloque un nuevo módulo proveedor en la ruta de módulos y se detectará automáticamente.

Esto permite crear arquitecturas de plugins y aplicar una inversión limpia de dependencias.

La fábrica provider()

Si la construcción requiere lógica, exponga un método estático y público provider() en lugar de un constructor sin argumentos. JPMS lo invocará para obtener la instancia.

package com.example.base64;

import com.example.spi.Codec;

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

Varios proveedores

Muchos módulos pueden proporcionar la misma interfaz. ServiceLoader devuelve todos los proveedores, lo que permite al consumidor elegir según el nombre, la prioridad o las capacidades.

Puede agregar o quitar proveedores sin modificar el código del consumidor.

Flujo de proveedores

Desde Java 9, ServiceLoader ofrece stream(), que produce referencias Provider que puede filtrar antes de crear las instancias; resulta útil cuando la construcción es 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());
    }
}

Comprobación rápida

Recuerde qué directiva utiliza cada función.

Resumen

Ha aprendido el patrón de servicios de los módulos:

  • Tres funciones: interfaz de servicio, proveedor y consumidor
  • Consumidor: uses; proveedor: provides ... with
  • Las implementaciones se cargan en tiempo de ejecución mediante ServiceLoader
  • Los proveedores necesitan un constructor público sin argumentos o un provider() estático

A continuación: migrar un proyecto existente a módulos.

Preguntas frecuentes

¿La lección «Servicios con provides/uses» es gratis?

Sí — el texto completo de «Servicios con provides/uses» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Java Academy, actualiza a CoddyKit PRO. El curso de Java Academy incluye 4 lecciones en total.

¿Qué aprenderé en «Servicios con provides/uses»?

Desacople mediante el cargador de servicios Practicas Java Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.

¿Necesito experiencia previa para empezar Java Academy?

No se requiere experiencia previa. Java Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.

¿Cuánto tiempo toma la lección «Servicios con provides/uses»?

La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.

¿Puedo escribir y ejecutar código en esta lección de Java Academy?

Sí. Cada lección de Java Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.

Todas las lecciones de este curso

  1. module-info.java
  2. requires y exports
  3. Servicios con provides/uses
  4. Migración a módulos
← Volver a Java Academy