Entendiendo los Spring Bean Scopes
Me preguntaba que ocurría dentro del contenedor de IOC de Spring con respecto a los ámbitos de sus objetos y esto fue lo que me encontre:
hay diferentes tipos de ámbito y ciclos de vida para los beans de Spring:
— Singleton: es el ciclo de vida por defecto. Únicamente se crea una instancia del bean dentro del contenedor IoC.
— Prototype: se crea una nueva instancia cada vez que se solicita el bean.
— Ciclos de vida únicamente válidos en el contexto de aplicaciones web:
- Request: se crea una única instancia por solicitud http.
- Session: se crea una única instancia por sesión http.
- Global-session: se crea una única instancia por sesión global. Se usa típicamente en contexto de Portlet.
- Application: el ciclo de vida del bean se acopla al ciclo de vida de un ServletContext.
- Websocket: el ciclo de vida se acopla al ciclo de vida de un WebSocket.
- Spring también permite la creación de ciclos de vida personalizados. Los ciclos de vida son extensibles, pudiendo definir un ciclo de vida a medida mediante la implementación de la interfaz Scope. No se pueden sobrescribir los ciclos de vida Singleton ni Prototype.
- Singleton Scope
Cuando definimos un bean con el alcance singleton, el contenedor crea una sola instancia de ese bean; todas las solicitudes de ese nombre de bean devolverán el mismo objeto, que se almacena en caché. Cualquier modificación al objeto se reflejará en todas las referencias al bean. Este ámbito es el valor predeterminado si no se especifica ningún otro ámbito.
@Bean
@Scope("singleton")
public Car car() {
return new Car();
}Alternativa:
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
- Prototype Scope
Un bean con el alcance de prototype devolverá una instancia diferente cada vez que se solicite desde el contenedor. Se define estableciendo el valor prototipo en la anotación @Scope en la definición del bean.
@Bean
@Scope("prototype")
public Car car() {
return new Car();
}Alternativa:
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
- Ámbitos Concernientes a la Web
Como se mencionó anteriormente, hay cinco ámbitos adicionales que solo están disponibles en un contexto de aplicación compatible con la web. Los usamos con menos frecuencia en la práctica. - Request Scope
Esto es lo mismo que el alcance del prototipo, sin embargo, está destinado a ser utilizado para aplicaciones web. Se creará una nueva instancia del bean para cada solicitud HTTP.
@Bean
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public Car car() {
return new Car();
}Alternativa:
@Bean
@RequestScope
public Car car() {
return new Car();
}
- Session Scope
El contenedor creará un nuevo bean para cada sesión HTTP.
@Bean
@SessionScope
public Car car() {
return new Car();
}
- Global SessionScope
Se utiliza para crear beans de sesión globales para aplicaciones de portlet.
@Component
@Scope("globalSession")
public class globalBeanTest {
}
Alternativa:
@Component
@GlobalSessionScope
public class globalBeanTest {
}
- Application Scope
En el alcance de la application, Spring crea una instancia de bean por tiempo de ejecución de la aplicación web. Es similar al alcance singleton, con una gran diferencia. El bean con ámbito de singleton es singleton por ApplicationContext donde el bean con ámbito de application es singleton por ServletContext. Tenga en cuenta que puede haber varios contextos de application para una sola aplicación.
@Bean
@Scope(
value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public Car car() {
return new Car();
}Alternativa:
@Bean
@ApplicationScope
public Car car() {
return new Car();
}
- Websocket Scope
Spring Framework proporciona una API de WebSocket que puede usar para escribir aplicaciones del lado del cliente y del servidor que manejen mensajes de WebSocket. Puede declarar un bean gestionado por Spring en el ámbito websocket. Por lo general, son singletons y duran más que cualquier sesión individual de WebSocket.
@Bean
@Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
public Car car() {
return new Car();
}
Tenga en cuenta que los ámbitos de solicitud, sesión, aplicación y wvebsocket solo están disponibles si utiliza una implementación de Spring ApplicationContext compatible con la web (como XmlWebApplicationContext). Si usa estos ámbitos con contenedores Spring IoC normales, como ClassPathXmlApplicationContext, obtiene una IllegalStateException quejándose de un ámbito de Bean desconocido.