Pregunta

Fondo: Entonces, tengo varios beans que interactúan con sistemas externos.Para el desarrollo, es conveniente burlarse de los sistemas externos y reemplazar los beans de interfaz con algunas implementaciones que produzcan respuestas más o menos estáticas.Entonces, lo que he estado haciendo es crear una interfaz, la implementación real y una implementación de código auxiliar como esta:

public interface ExternalService {
// ...
}

@Service
public class ExternalServiceImpl implements ExternalService {
// ...
}

@Service
@Primary
@Profile({"stub"})
public class StubExternalService implements ExternalService {
// ...
}

...y esto funciona muy bien:Si el perfil stub no está presente, el stub-bean no se carga en absoluto.Si está presente, reemplaza la implementación real debido a la anotación @Primary.

Problema: Ahora, sin embargo, he corrido por primera vez en una situación en la que tengo dos implementaciones reales de la misma interfaz.Uno de ellos se define como principal, pero el otro también se puede utilizar cargándolo desde el contexto de la aplicación.

Todavía me gustaría crear un servicio de código auxiliar para reemplazarlos a ambos, pero esta vez mi antigua forma de definir el código auxiliar como @Primary no funciona porque ya existe una implementación principal.Básicamente, lo que necesitaría es una forma de no cargar el bean principal cuando se configura el perfil de código auxiliar, pero no sé cómo hacerlo exactamente.Las búsquedas web u otras preguntas de Stack Overflow no parecen ayudar.

¿Fue útil?

Solución

Resulta que la respuesta fue sorprendentemente simple:agregas un no operador (!) delante del nombre del perfil:

@Service
@Primary
@Profile({"!stub"})
public class ExternalServiceImpl implements ExternalService {
// ...
}

De esta manera el frijol sólo se carga cuando el stub-el perfil no está activo.El soporte para esta característica se agregó en Muelle 3,2 M1.

Sin embargo, hay una advertencia:Si tú escribes @Profile({"!stub", "foo"}), la coma se trata como "o", no como "y".Entonces este bean de ejemplo se activaría si stub no estaba activo o si foo estaba activo.

Editar/Agregar: Spring 5.1 agregó soporte para un nuevo lenguaje de expresión para perfiles: !stub & foo se activa cuando stub no está activo y foo está activo.¡Gran éxito!Incluso puedes mezclar y combinar ands y ors siempre que uses paréntesis: production & (us-east | eu-central).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top