Es hora de empezar a ver algunos de los numerosos atributos que se pueden utilizar a la hora de definir beans, ya que es necesario recordar en todo momento que un contexto de Spring implementa un patrón Factory que es capaz de instanciar virtualmente cualquier clase que se le defina en la práctica, y para poder lograrlo tiene que poder dejarnos indicarle que es exactamente lo que queremos instanciar y como lo queremos instanciar.

Nombres

En el ejemplo básico del artículo anterior se utilizó el atributo id para identificar a un bean. Los identificadores deben ser únicos en un sistema, elevándose una excepción en caso contrario. Si un identificador se omite, Spring creará uno automáticamente.

También se permite tener más de un nombre para un mismo bean. Ya sea utilizando el atributo name, que admite una lista de nombres separados por espacios (” “), comas (“,”), o puntos y comas (“;”). O utilizando la etiqueta alias:

Con esta configuración de ejemplo el mismo bean podría referenciarse como “zoo”, “zoologico”, “wildPark”, “zooBean” o “wildParkZoo”.

Instanciación

Spring puede instanciar un bean de muy diversas formas. La más básica es la del ejemplo básico del artículo anterior. Es decir, usando un simple constructor sin parámetros.

Otra forma de hacerlo es proporcionándole a Spring el nombre de un método estático de la clase que implemente el patrón Factory:

Lo que permite utilizar la típica implementación del patrón Singleton sin renunciar a Spring:

E incluso es posible indicar que se utilice otra clase (bean) para que sea esa la que actúe con el rol de Factory:

En este último ejemplo es interesante notar que el atributo factory-bean hace referencia a un bean. Utilizar referencias a otros beans es una constante dentro de los ficheros de configuración.

Con esta configuración podemos eliminar el método estático del ejemplo anterior e implementar una clase factoría más tradicional:

No obstante, lo realmente importante es darse cuenta de que la implementación del método main original no se ha cambiado en ningún momento, la forma de acceder al bean sigue siendo la misma desde el principio. Es decir, sólo es necesario cambiar la configuración de Spring para variar la forma en la que instancian los objetos dentro de nuestra aplicación. Esto permite poder establecer la estrategia que resulte más adecuada en cualquier momento del ciclo de vida de una aplicación sin tener que modificar y recompilar el código.

Dependencias

La inyección de dependencias permite indicar, mediante configuración, no de forma explícita en el código, que beans concretos deben utilizar otros beans. Es decir, que componentes concretos debe utilizar la aplicación. En la práctica significa delegar en Spring la instanciación de los parámetros de los constructores o de las propiedades de las clases.

Imaginemos que queremos montar restaurantes en nuestro zoológico y estamos barajando varias opciones, como puestos de comida rápida, cocina mediterránea o algo más exótico. Creamos una interface, lo dejamos abierto a las diversas implementaciones posibles, pero forzamos a que se pase como parámetro en el constructor:

En la configuración le indicamos a Spring el componente (bean) concreto queremos utilizar con la etiqueta constructor-arg. Por ejemplo, si nos decidiéramos por una cadena de restaurantes de comida mejicana podríamos utilizar la siguiente configuración:

De forma general, con este tipo de configuraciones lo que hace Spring es casar los argumentos por tipo, y si la configuración resulta ambigua entonces eleva una excepción.

Si se quiere más control se puede indicar el tipo concreto de cada parámetro y su valor:

O indicar la posición concreta que ocupa cada parámetro:

E incluso utilizar el nombre original de los parámetros:

Aunque esto último sólo funciona si se compila en modo debug o se usa la anotación @ConstructorProperties del JDK.

Otra forma distinta de pasarle las dependencias a una clase es utilizar setters una vez esté instanciada en vez de utilizar parámetros en el constructor:

En este caso, para inyectar las dependencias, se utiliza la etiqueta property con el nombre del atributo de la clase correspondiente, tantas como se quieran inyectar:

De forma parecida a ejemplos anteriores, el atributo ref sirve para referenciar a otro “bean”, objeto de estudio del siguiente capítulo.