Volver a la página principal
martes 1 octubre 2024
22

Cómo habilitar beans con @ConditionalOnProperty en Spring Boot

La anotación @ConditionalOnProperty en Spring Boot se utiliza para habilitar o deshabilitar automáticamente componentes, beans o configuraciones en función del valor de una propiedad especificada en los archivos de configuración (application.properties o application.yml). Es una herramienta muy útil para realizar configuraciones condicionales basadas en el entorno, habilitar características opcionales, o gestionar configuraciones personalizadas según el estado de propiedades.

¿Qué es @ConditionalOnProperty en Spring Boot?

@ConditionalOnProperty es una anotación que forma parte del paquete org.springframework.boot.autoconfigure.condition y se utiliza para controlar la creación de beans y la ejecución de configuraciones en Spring Boot según el valor de una propiedad. Permite definir condiciones basadas en propiedades de configuración, como application.properties o variables de entorno.

Atributos principales de @ConditionalOnProperty

  • prefix: Especifica el prefijo de la propiedad, lo que ayuda a agrupar configuraciones.
  • name: Define el nombre específico de la propiedad.
  • havingValue: Indica el valor que debe tener la propiedad para que el bean se habilite (por defecto, se activa si la propiedad está presente y no es false).
  • matchIfMissing: Si se establece en true, el bean se registra incluso si la propiedad no está presente (valor predeterminado: false).

Ejemplos de uso de @ConditionalOnProperty en Spring Boot

1. Habilitar un bean según una propiedad

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    @ConditionalOnProperty(name = "mi.feature.habilitada", havingValue = "true")
    public MiServicio miServicio() {
        return new MiServicio();
    }
}

En este ejemplo:

  • El bean MiServicio solo se creará si la propiedad mi.feature.habilitada está definida en application.properties con el valor true:
mi.feature.habilitada=true
  • Si la propiedad tiene otro valor (false) o no está presente, el bean no se registrará en el contexto de Spring.

2. Definir un prefijo de propiedad con prefix y name

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ServicioConfig {

    @Bean
    @ConditionalOnProperty(prefix = "mi.aplicacion", name = "modo", havingValue = "produccion")
    public ServicioProduccion servicioProduccion() {
        return new ServicioProduccion();
    }

    @Bean
    @ConditionalOnProperty(prefix = "mi.aplicacion", name = "modo", havingValue = "desarrollo")
    public ServicioDesarrollo servicioDesarrollo() {
        return new ServicioDesarrollo();
    }
}

En este caso:

  • Se usa prefix = "mi.aplicacion" para agrupar las propiedades.
  • Si mi.aplicacion.modo=produccion, se registra el bean ServicioProduccion.
  • Si mi.aplicacion.modo=desarrollo, se activa ServicioDesarrollo.
  • Esta configuración permite tener diferentes beans según el entorno (producción o desarrollo).

3. Activar un bean cuando falta una propiedad usando matchIfMissing

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ConfiguracionDefecto {

    @Bean
    @ConditionalOnProperty(name = "mi.configuracion.personalizada", havingValue = "true", matchIfMissing = true)
    public ConfiguracionDefectoBean configuracionPorDefecto() {
        return new ConfiguracionDefectoBean();
    }
}

En este ejemplo:

  • El bean ConfiguracionDefectoBean se habilita si mi.configuracion.personalizada=true.
  • También se habilita si la propiedad mi.configuracion.personalizada no está definida, gracias a matchIfMissing = true.
  • Esto es útil para establecer configuraciones predeterminadas en ausencia de propiedades específicas.

4. Usar @ConditionalOnProperty en una clase de configuración

import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;

@Configuration
@ConditionalOnProperty(name = "feature.nueva", havingValue = "enabled")
public class NuevaFeatureConfig {

    // Definir beans o configuraciones adicionales para esta característica
}

En este caso:

  • Toda la clase NuevaFeatureConfig y sus definiciones de beans se cargarán solo si la propiedad feature.nueva está establecida como enabled:
feature.nueva=enabled
  • Esta técnica es útil para activar módulos completos de la aplicación basados en una propiedad.

5. Combinar @ConditionalOnProperty con otras anotaciones condicionales

Puedes combinar @ConditionalOnProperty con otras anotaciones condicionales como @ConditionalOnClass, @ConditionalOnMissingBean, y @ConditionalOnBean para crear configuraciones más complejas:

import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ConfiguracionCombinada {

    @Bean
    @ConditionalOnProperty(name = "feature.combinada", havingValue = "true")
    @ConditionalOnBean(MiServicio.class) // Este bean solo se crea si existe MiServicio
    public ServicioCombinado servicioCombinado() {
        return new ServicioCombinado();
    }
}

En este ejemplo:

  • servicioCombinado solo se creará si feature.combinada=true y MiServicio ya está definido como un bean en el contexto de Spring.

¿Cuándo usar @ConditionalOnProperty?

Se debe usar @ConditionalOnProperty cuando:

1. Deseas activar o desactivar configuraciones según el entorno (por ejemplo, desarrollo o producción).

2. Quieres habilitar características opcionales basadas en valores definidos en los archivos de configuración.

3. Necesitas crear beans de prueba que se habilitan solo en ciertos contextos.

4. Quieres establecer configuraciones predeterminadas en caso de que una propiedad esté ausente (matchIfMissing = true).

Diferencia entre @ConditionalOnProperty y otras anotaciones condicionales

  • @ConditionalOnMissingBean: Se usa para cargar beans si un bean específico no está presente.
  • @ConditionalOnClass: Se utiliza para registrar beans solo si una clase específica está disponible en el classpath.
  • @ConditionalOnProperty: Habilita o deshabilita beans basándose en el valor de una propiedad de configuración.

Referencia oficial

Para obtener más detalles sobre @ConditionalOnProperty, consulta la documentación oficial de Spring.

Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer