Anotación de Spring @ConditionalOnProperty

@ConditionalOnProperty con Spring

@ConditionalOnProperty con Spring


En esta entrada de Refactorizando sobre la anotación de Spring @ConditionalOnProperty vamos a profundizar en este Bean Condicional.

¿Qué son los bean condicionales en Spring?

Spring nos ofrece una funcionalidad para poder realizar la inyección de un bean en el contexto de la aplicación. Para ello podemos hacer uso del @Condition con lo que evitaremos la inyección de un bean en función de unas condiciones.

Podemos encontrarnos diferentes anotaciones para establecer una condición para inyectar el Bean, en este caso vamos a ver como podemos utilizar el @ConditionalOnProperty para inyectar o no en el contexto tun Bean.

En resumen, @ConditionalOnProperty activa el registro del Bean únicamente si una propiedad que es configurable, esta presente.

¿Para qué usar @ConditionalOnProperty?

Un @ConditionalOnProperty puede ser de gran utilidad cuando tenemos dos beans del mismo tipo y en función de nuestra necesidad queremos inyectar uno u otro.

Por ejemplo, imagina que tenemos una aplicación de comida a domicilio, y en función de nuestras necesidades aceptamos pedidos por teléfono o por email, para ese caso podemos crear dos bean y en función de una property se inyecta un Bean (email) u otro Bean (teléfono).

Ejemplo de @ConditionalOnProperty en Spring

A continuación vamos a ver un ejemplo de utilización de @ConditionalOnProperty en Spring. Basándonos en el ejemplo del que hemos hablado en el punto anterior, vamos a crear una interfaz con dos implementaciones diferentes.

public interface NotificationOrder {

    String Order(String order);

}

A continuación vamos a crear dos clases que implementen NotificationOrder:

public class PhoneOrder implements NotificationOrder {
    @Override
    public String Order(String order) {
        return "Phone Order " + order;
    }
}
public class EmailOrder implements NotificationOrder {
    @Override
    public String Order(String order) {
        return "Email Order " + order;
    }
}

Y finalmente en nuestro application.yml vamos a agregar la siguiente propiedad:

notification.order: email

Activar o desactivar Bean con @ConditionalOnProperty

A continuación vamos a crear el Bean NotificationOrder en función de una propiedad, es decir, si tiene la propiedad que pasamos por parámetro el Bean se inyecta en el application context de nuestra aplicación.

@Bean(name = "emailOrder")
@ConditionalOnProperty(value = "notification.order", havingValue = "email")
public NotificationOrder emailOrder() {
    return new EmailOrder();
}

En el caso anterior hemos inyectado y creado el bean emailOrder debido que tenemos la propiedad «notification.order: email». En lugar de utilizar la propiedad value también podemos hacer uso de prefix y name, por ejemplo:

@Bean(name = "emailOrder")
@ConditionalOnProperty(prefix = "notification", name = "order")
public NotificationOrder emailOrder() {
    return new EmailOrder();
}

Con el código anterior el Bean será cargado si la propiedad que hemos pasado por parámetros se encuentra, por lo que en nuestro caso sí será cargada.

Cargar un Bean u otro con @ConditionalOnProperty

Vamos a volver al caso en el que o cargamos el Bean EmailOrder o PhoneOrder en función de propiedades.

Para ello vamos a añadir el siguiente código:

@Bean(name = "emailOrder")
@ConditionalOnProperty(prefix = "notification", name = "order", havingValue = "email")
public NotificationOrder emailOrder() {
    return new EmailOrder();
}

@Bean(name = "phoneOrder")
@ConditionalOnProperty(prefix = "notification", name = "order", havingValue = "phone")
public NotificationOrder phoneOrder() {
    return new PhoneOrder();
}

Con el código anterior vamos a registrar únicamente un Bean, para ello vamos a hacer uso de la propiedad havingValue, con lo que uno y solo un bean será añadido al contenedor de Spring.

Como nota adicional, tenemos la propiedad matchIfMissing, que lo que nos dice es que debe hacer ese Bean en caso de que la propiedad no este definida, por defecto es false. Vamos a verlo en código:

@Bean(name = "phoneOrder")
@ConditionalOnProperty(prefix = "notification", name = "order", havingValue = "phone",  matchIfMissing = true)
public NotificationOrder phoneOrder() {
    return new PhoneOrder();
}

Conclusión

En esta entrada sobre Anotación de Spring @ConditionalOnProperty hemos entrado más en detalle como realizar una inyección de Bean en el contenedor de Spring en función de una propiedad externalizada.

Si necesitas más información puedes escribirnos un comentario o un correo electrónico a refactorizando.web@gmail.com o también nos puedes contactar por nuestras redes sociales Facebook o twitter y te ayudaremos encantados!


Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *