Alcance singleton

Solo se administra una instancia compartida de un bean singleton, y todas las solicitudes a beans con un identificador o identificadores que coincidan con la definición de ese bean dan como resultado que el contenedor Spring devuelva esa instancia de bean en particular.

En otras palabras, cuando asigna una definición de bean y entra en el ámbito singleton, el contenedor Spring IoC crea exactamente una instancia del objeto asignado por esa definición de bean. Esta instancia única se almacena en la memoria caché de dichos beans singleton, y todas las solicitudes y referencias posteriores a este bean con nombre devuelven el objeto almacenado en caché. La siguiente imagen muestra cómo funciona el alcance singleton:

El concepto de bean singleton en Spring es diferente del concepto de plantilla singleton tal como se define en el libro de patrones Gang of Four/GoF. En el caso de un objeto singleton GoF, el alcance del objeto está codificado de manera que para cada ClassLoader, se crea una y solo una instancia de la clase concreta. El alcance singleton en Spring se describe mejor como por contenedor y por frijol. Esto significa que si define un bean para una clase particular en un contenedor Spring, el contenedor Spring crea una y solo una instancia de la clase definida por esa definición de bean. El alcance singleton es el alcance predeterminado de Spring. Para definir un bean como un objeto singleton en XML, puede definir el bean de la manera que se muestra en el siguiente ejemplo:

<bean id="accountService" class="com.something.DefaultAccountService"/>
<!-- lo siguiente es equivalente, aunque redundante (el alcance singleton se usa de forma predeterminada) -->
<bean id="accountService" class="com.something.DefaultAccountService" alcance="singleton"/>

Alcance del prototipo

El alcance del prototipo no único para la implementación de beans crea una nueva instancia del bean cada vez que se realiza una solicitud para ese bean en particular. Es decir, un bean se inyecta en otro bean o se solicita mediante una llamada al método getBean() en el contenedor. En general, debe utilizar el alcance prototipo para todos los beans con estado y el alcance singleton para los beans sin estado.

El siguiente diagrama ilustra el alcance del prototipo en Spring:

(El objeto de acceso a datos (DAO) normalmente no se configura como un prototipo porque un DAO típico no retiene ningún estado de diálogo. Fue más fácil reutilizar el esquema central para un objeto singleton).

El siguiente ejemplo define el bean como un prototipo en XML:

<bean id="accountService" class="com.something.DefaultAccountService" alcance="prototype"/>

A diferencia de otros ámbitos, Spring no gestiona el ciclo de vida completo del bean prototipo. El contenedor crea una instancia, configura y, de otro modo, ensambla un objeto prototipo y lo pasa al cliente, sin escribir más sobre esa instancia prototipo. Por lo tanto, aunque los métodos de devolución de llamada del ciclo de vida de inicialización se invocan en todos los objetos independientemente del alcance, en el caso de prototipos, no se invocan las devoluciones de llamada del ciclo de vida de destrucción configuradas. El código del cliente debe limpiar los objetos que están en el alcance del prototipo y liberar recursos valiosos que consumen los beans prototipo. Para forzar que el contenedor Spring libere los recursos consumidos por los beans dentro del alcance del prototipo, intente utilizar un postprocesador de beans especial que contenga una referencia a los beans que deben limpiarse.

En cierto sentido, la función del contenedor Spring con respecto a los beans con ámbito de prototipo es un reemplazo del operador new de Java. Toda la gestión del ciclo de vida posterior a este punto debe realizarse en el lado del cliente. (Para obtener más información sobre el ciclo de vida del bean en un contenedor Spring, consulte Devoluciones de llamada del ciclo de vida).

Bean individuales con dependencias de prototipo-bean

Si utiliza beans de ámbito único con dependencias de beans prototipo, recuerde que las dependencias se resuelven cuando se crea la instancia. Por lo tanto, si inyecta una dependencia de un bean prototipo en un bean que está en el alcance de un singleton, se crea una instancia del nuevo bean prototipo y luego se inyecta en el bean singleton. Una instancia de prototipo es una instancia única que se proporciona a un bean dentro del alcance de un singleton.

Sin embargo, supongamos que desea que un bean con ámbito único reciba repetidamente nuevas instancias de un bean con ámbito de prototipo en tiempo de ejecución. No podrá inyectar una dependencia de un bean con ámbito de prototipo en su bean singleton porque la inyección ocurre solo una vez, cuando el contenedor Spring crea una instancia del bean singleton, resuelve e inyecta sus dependencias.