CodeGym /Cursos /Módulo 5. Spring /Scopes de beans (singleton, prototype y demás)

Scopes de beans (singleton, prototype y demás)

Módulo 5. Spring
Nivel 2 , Lección 5
Disponible

Un scope (Scope) en Spring es una regla que define el ciclo de vida de un bean: cuándo crear una nueva instancia del objeto, cuánto tiempo mantenerla y cuándo destruirla. Es parecido a las reglas de gestión de recursos: algunos recursos hay que crear una vez y reutilizarlos, y otros requieren una nueva instancia en cada acceso.

Los scopes son importantes porque distintas partes de tu aplicación pueden tener diferentes requisitos para la creación de objetos. Por ejemplo:

  • Para servicios "sin estado" (stateless), queremos usar la misma instancia en toda la aplicación.
  • Y para objetos que almacenan datos únicos por cada petición HTTP, necesitamos una nueva instancia para cada petición.

En un proyecto real, entender los scopes te ayuda a gestionar recursos de forma flexible y a mejorar el rendimiento de la aplicación.


Scopes estándar en Spring

Veamos los scopes principales de Spring:

  1. Singleton (por defecto)
  2. Prototype
  3. Request
  4. Session
  5. Application

Singleton: "Uno para todos"

Singleton es el scope por defecto. Cuando un bean está marcado con este scope (o no está marcado), Spring crea solo una instancia del bean por todo el ApplicationContext. Ese bean se reutilizará cada vez que se solicite.


@Component
public class SingletonExample {
    public SingletonExample() {
        System.out.println("Singleton bean creado");
    }
}

Si añades el bean anterior en dos partes diferentes de la aplicación, por ejemplo en dos clases distintas, Spring creará una única instancia y la inyectará en ambos. Aquí tienes un ejemplo:


@Component
public class MyService {

    private final SingletonExample singletonExample;

    @Autowired
    public MyService(SingletonExample singletonExample) {
        this.singletonExample = singletonExample;
        System.out.println("MyService recibió el bean SingletonExample");
    }
}

@Component
public class AnotherService {

    private final SingletonExample singletonExample;

    @Autowired
    public AnotherService(SingletonExample singletonExample) {
        this.singletonExample = singletonExample;
        System.out.println("AnotherService recibió el bean SingletonExample");
    }
}

Resultado:


Singleton bean creado
MyService recibió el bean SingletonExample
AnotherService recibió el bean SingletonExample

Prototype: "Una nueva instancia por cada petición"

Prototype es el scope para casos en los que necesitas una nueva instancia del bean en cada petición. Esto es útil si el bean contiene estado que cambia según la lógica de negocio.


@Component
@Scope("prototype")
public class PrototypeExample {
    public PrototypeExample() {
        System.out.println("Prototype bean creado");
    }
}

Si dos componentes distintos solicitan PrototypeExample, Spring creará dos instancias separadas.


@Component
public class MyPrototypeService {

    private final PrototypeExample prototypeExample;

    @Autowired
    public MyPrototypeService(PrototypeExample prototypeExample) {
        this.prototypeExample = prototypeExample;
        System.out.println("MyPrototypeService recibió el bean PrototypeExample");
    }
}

@Component
public class AnotherPrototypeService {

    private final PrototypeExample prototypeExample;

    @Autowired
    public AnotherPrototypeService(PrototypeExample prototypeExample) {
        this.prototypeExample = prototypeExample;
        System.out.println("AnotherPrototypeService recibió el bean PrototypeExample");
    }
}

Resultado:


Prototype bean creado
MyPrototypeService recibió el bean PrototypeExample
Prototype bean creado
AnotherPrototypeService recibió el bean PrototypeExample

Request: "Nuevo bean para cada petición HTTP"

Este scope se usa en aplicaciones web. Para cada nueva petición HTTP se crea una instancia separada del bean.


@Component
@Scope("request")
public class RequestScopedBean {
    public RequestScopedBean() {
        System.out.println("Request bean creado");
    }
}
⚠️ Atención:

usar este scope solo es posible en una aplicación con soporte de contexto web, por ejemplo con Spring MVC.

Session: "Un bean por sesión de usuario"

Session-scope crea un bean único por cada sesión de usuario.


@Component
@Scope("session")
public class SessionScopedBean {
    public SessionScopedBean() {
        System.out.println("Session bean creado");
    }
}

Application: "Un bean para todo el contexto de la aplicación"

Este scope es parecido a singleton, pero es específico para aplicaciones web con varios servlets. El bean se crea una vez y se usa en todos los servlets de la aplicación.


¿Cómo configurar los scopes?

Puedes configurar los scopes usando la anotación @Scope. Aquí tienes un ejemplo de cómo indicar el scope para un bean:


@Component
@Scope("prototype") // Indicamos el scope para este bean
public class MyPrototypeBean {
    // Lógica del bean
}

Para los scopes orientados a web (request, session, application) puedes usar el mismo enfoque.

¿Cómo elegir el scope correctamente?

Singleton es ideal para servicios sin estado. Por ejemplo, un servicio de envío de email — simplemente ejecuta la acción y no guarda datos.

Prototype hace falta cuando cada usuario necesita su propia instancia. Imagina un formulario de registro — cada uno tiene sus propios datos.

Request/Session ayudan a trabajar con datos web. Por ejemplo, el carrito en una tienda online vive dentro de la sesión del usuario.

Atención: la elección del scope afecta a la memoria y al rendimiento. Usa con cuidado el prototype — cada nueva instancia consume memoria y hay que liberarla a tiempo.

Errores típicos al usar scopes

  1. Uso de prototype beans dentro de singleton beans: si inyectas un prototype bean en un singleton mediante DI,
  2. Spring creará solo una instancia del prototype y la "pegará" al singleton. Para arreglarlo puedes usar la interfaz ObjectFactory o la anotación @Lookup.

  3. Intentar usar scopes orientados a web en una aplicación NO web: en ese caso recibirás el error No Scope Registered for ScopeName.


Ahora puedes trabajar con confianza con los scopes en Spring Framework, usándolos para crear aplicaciones flexibles y escalables. En la siguiente clase veremos las anotaciones @Configuration y @Bean, que te ayudarán a gestionar mejor las configuraciones y las fábricas de beans.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION