Implementación de un Starter Personalizado para Generación de Identificadores Distribuidos con Redis

Encapsulamiento de lógica de identificación distribuida mediante un Starter personalizado

Para centralizar la creación de identificadores únicos basados en Redis y hacerlos reutilizables a lo largo de múltiples servicios, es posible empaquetar esta lógica dentro de un Spring Boot Starter independiente. Esto permite que otros módulos consuman la funcionalidad simplemente agregando una dependencia, eliminando código duplicado y estandarizando el comportamiento.

1. Desarrollo de la capa de generación

Se define una clase encargada de orquestar el incremento atómico en Redis junto con el cálculo del desplazamiento temporal. Se utiliza inyección de dependencias por constructor para garantizar la inmutabilidad y se corrige el uso de anotaciones de capa web, ya que un starter debe proveer servicios, no controladores.

package io.devtools.idgenerator.core;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;

@Service
public class DistributedSequenceProvider {

    private static final long BASE_EPOCH = LocalDate.of(2023, 1, 1).atStartOfDay(ZoneOffset.UTC).toEpochSecond();
    private final StringRedisTemplate redisOps;

    public DistributedSequenceProvider(StringRedisTemplate redisOps) {
        this.redisOps = redisOps;
    }

    public long generate(String businessContext) {
        LocalDate currentDate = LocalDate.now(ZoneOffset.UTC);
        long timeDelta = ChronoUnit.SECONDS.between(LocalDate.of(2023, 1, 1), currentDate);

        String todayPattern = currentDate.toString(); // Formato ISO-8601: yyyy-MM-dd
        String redisKey = "unique_seq:" + businessContext + ":" + todayPattern;

        long counterPart = redisOps.opsForValue().increment(redisKey);

        // Estructura de 64 bits: 32 bits para delta temporal + 32 bits para contador diario
        return (timeDelta << 32) | (counterPart & 0xFFFFFFFFL);
    }
}

2. Definición de la autoconfiguración

El motor de arranque requiere una clase de configuración que exponga los beans necesarios al contexto de la aplicación. Se añade una condición condicional para asegurar que el starter solo se active si está presente la integración de Redis, evitando errores de arranque en proyectos que no lo utilicen.

package io.devtools.idgenerator.config;

import io.devtools.idgenerator.core.DistributedSequenceProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;

@Configuration
@ConditionalOnClass(StringRedisTemplate.class)
public class IdGeneratorAutoConfiguration {

    @Bean
    public DistributedSequenceProvider sequenceProvider(StringRedisTemplate template) {
        return new DistributedSequenceProvider(template);
    }
}

3. Registro del mecanismo de carga automática

Para que Spring Boot detecte y cargue la configuración al iniciar el contexto, es necesario registrar la clase dentro del archivo de factorías. En versiones modernas del framework, también puede utilizarse el archivo spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports, aunque la ruta tradicional sigue siendo ampliamente soportada.

# src/main/resources/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  io.devtools.idgenerator.config.IdGeneratorAutoConfiguration

4. Publicación en el repositorio local

Una vez estructurados los componentes, se compila y distribuye el artefacto ejecutando el comando mvn clean install en la raíz del proyecto. Esto genera el archivo JAR y lo deposita en el repositorio de Maven local, listo para ser consumido por otros servicios.

5. Integración en proyectos externos

La incorporación del starter en aplicaciones cliente implica los siguientes pasos:

  • Agregar la dependencia del nuevo artefacto en el archivo pom.xml del servicio consumiodr.
  • Inyectar DistributedSequenceProvider mediante @Autowired o @Resource en los controladores o servicios de negocio.
  • Configurar las credenciales y el endpoint de Redis en application.yml o application.properties. El starter heredará automáticamente la configuración existente de spring-data-redis, por lo que no se requieren propiedades adicionales a menos que se implemente validación de umbrales o límites de rate-limiting.

Etiquetas: Spring Boot Redis Auto-configuration maven java

Publicado el 8-9 06:24