In Spring the scope of a bean defines the lifecycle and visibility of that bean in the Spring container. There are six scopes:

- Singleton: default, one instance per Spring container
- Prototype: a new instance per bean request
- Request: a new instance per HTTP request
- Session: a new instance per HTTP session
- Application: a new instance per ServletContext
- Websocket: a new instance per Websocket session

The last four scopes mentioned, request, session, application and websocket, are only available in a web-aware application.

## Why is this an issue?

In Spring, singleton beans and their dependencies are initialized when the application context is created.

If a `Singleton` bean depends on a bean with a shorter-lived scope (like `Request` or `Session` beans), it retains the same instance of that bean, even when new instances are created for each Request or Session. This mismatch can cause unexpected behavior and bugs, as the Singleton bean doesn’t interact correctly with the new instances of the shorter-lived bean.

This rule raises an issue when non-singleton beans are injected into a singleton bean.

### What is the potential impact?

When a `Singleton` bean has a dependency on a bean with a shorter-lived scope, it can lead to the following issues:

- Data inconsistency: any state change in the shorter-lived bean will not be reflected in the Singleton bean.
- Incorrect behavior: using the same instance of the shorter-lived bean, when a new instance is supposed to be created for each new request or session.
- Memory leaks: preventing garbage collection of a shorter-lived bean that allocates a significant amount of data over time.

## How to fix it

Inject a shorter-lived bean into a `Singleton` bean using ApplicationContext, Factories or Providers.

### Code examples

#### Noncompliant code example

When a `Singleton` bean auto-wires a `Request` bean, the dependency is resolved at instantiation time and thus the same instance is used for each HTTP request.

    @Component
    @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public class RequestBean {
        //...
    }

    public class SingletonBean {
        @Autowired
        private final RequestBean requestBean; // Noncompliant, the same instance of RequestBean is used for each HTTP request.

        public RequestBean getRequestBean() {
            return requestBean;
        }
    }

#### Compliant solution

Instead, use a `ObjectFactory<RequestBean>`, `ObjectProvider<RequestBean>`, or `Provider<RequestBean>` as injection point (as for JSR-330).

Such a dependency is resolved at runtime, allowing for actual injection of a new instance of the shorter-lived bean on each HTTP request.

    @Component
    @Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
    public class RequestBean {
        //...
    }

    public class SingletonBean {
        private final ObjectFactory<RequestBean> requestBeanFactory;

        @Autowired
        public SingletonBean(ObjectFactory<RequestBean> requestBeanFactory) {
            this.requestBeanFactory = requestBeanFactory;
        }

        public RequestBean getRequestBean() {
            return requestBeanFactory.getObject();
        }
    }

#### Noncompliant code example

When a `Singleton` bean auto-wires a `Prototype` bean, the dependency is resolved at instantiation time and thus the same instance is used for each bean request.

    @Component
    @Scope("prototype")
    public class PrototypeBean {
        public Object execute() {
          //...
        }
    }

    public class SingletonBean {
        private PrototypeBean prototypeBean;

        @Autowired
        public SingletonBean(PrototypeBean prototypeBean) { // Noncompliant, the same instance of PrototypeBean is used for each bean request.
          this.prototypeBean = prototypeBean;
        }

        public Object process() {
            return prototypeBean.execute();
        }
    }

#### Compliant solution

Using the `ApplicationContext` to retrieve a new instance of a `Prototype` bean on each bean request.

    @Component
    @Scope("prototype")
    public class PrototypeBean {
        public Object execute() {
          //...
        }
    }

    public class SingletonBean implements ApplicationContextAware {
        private ApplicationContext applicationContext;

        @Autowired
        public SingletonBean(ApplicationContext applicationContext) {
          this.applicationContext = applicationContext;
        }

        public Object process() {
            PrototypeBean prototypeBean = createPrototypeBean();
            return prototypeBean.execute();
        }

        protected PrototypeBean createPrototypeBean() {
            return this.applicationContext.getBean("prototypeBean", PrototypeBean.class);
        }
    }

## Resources

### Documentation

- Spring Framework - Factory Scopes
- Spring Framework - Beans Inject Named
- Spring Framework - Method Injection

### Articles & blog posts

- Baeldung - Spring Bean Scopes