12 de marzo de 2020

Sobrescribir un bean con XML

En la entrada anterior hemos sustituido un fichero de configuración (para crear un bean por XML) por otro (realizar escaneo de @Component). ¿Qué pasaría si usaramos los dos a la vez?

En ese caso tendríamos dos bean asociados con un mismo tipo. Los bean por defecto son objetos Singleton y al definir el bean va a haber dos definiciones distintas (Test por XML y por @Component). Para este caso Spring tiene un orden de prioridad que descartará definiciones menos prioritarias: XML > Componentes escaneados.

Simplemente juntando las dos configuraciones vamos a ver en la consola lo siguiente:
  • Si ponemos primero nuestro fichero config-scan.xml se crean 7 beans (nuestra sólo es una, la que se llama "test", las otras 6 son propias de Spring) y se sobrescribe 1 sólo que es la nuestra porque es la repetida.
  • Si invertimos el orden a la hora de crear el contenedor veremos lo contrario: se detecta 1 bean, el nuestro, y luego se añaden otros 6 más, descartando el bean repetido menos prioritario.

Este sería el código para el primer ejemplo donde por consola se puede ver cómo se hace esta sobrescritura:
ConfigurableApplicationContext context = 
        new ClassPathXmlApplicationContext(
                   new String[]{"config-scan.xml", "config.xml"});
Por consola las líneas clave son estas tres:
19:25:33.268 [main] DEB...XmlBeanDefinitionReader - Loaded 7 bean definitions from class path resource [config-scan.xml]
19:25:33.299 [main] DEB...DefaultListableBeanFactory - Overriding bean definition for bean 'test' with a different definition: replacing [Generic bean: class [es.lanyu.Test]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [E:\Desarrollo\DatosDeportivos2020\Spring-contenedor-dependencias\build\classes\java\main\es\lanyu\Test.class]] with [Generic bean: class [es.lanyu.Test]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=init; destroyMethodName=null; defined in class path resource [config.xml]]
19:25:33.299 [main] DEB...XmlBeanDefinitionReader - Loaded 0 bean definitions from class path resource [config.xml]
Esto tiene todo el sentido del mundo: Los beans definidos por anotaciones están altamente acoplados al código, probablemente no tendremos acceso al código fuente o no queramos modificarlo pues es una librería de un tercero que no mantenemos nosotros. Por el contrario, la configuración XML está completamente desacoplada y es la única forma que tendríamos de modificar la configuración de un bean que no vamos a modificar por código. Por esta razón la configuración XML prevalece sobre el resto.

Puedes ver el código en este punto en el repositorio de GitHub y el video del webinar en este momento.


En la siguiente entrada vamos a ver cómo desambiguar dos beans que cubren una misma dependencia.

No hay comentarios:

Publicar un comentario

Compárteme

Entradas populares