Gymterview
junior

Какие существуют scope у Spring Bean?

Scope определяет, сколько экземпляров бина будет создано и как они будут разделяться.

Scope Описание
singleton (по умолчанию) Один экземпляр на весь контейнер
prototype Новый экземпляр при каждом запросе бина
request Один экземпляр на HTTP-запрос (только для веб)
session Один экземпляр на HTTP-сессию (только для веб)
application Один экземпляр на ServletContext (только для веб)
websocket Один экземпляр на WebSocket-сессию
Пример
@Component
@Scope("prototype")
public class PrototypeBean { }

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

Проблема singleton-prototype

Если prototype-бин внедряется в singleton, он будет создан один раз и больше не изменится:

Пример
@Component // singleton по умолчанию
public class SingletonService {
    @Autowired
    private PrototypeBean prototypeBean; // ПРОБЛЕМА: всегда один и тот же экземпляр!
}

Решения

Пример
// 1. Через ObjectProvider
@Component
public class SingletonService {
    @Autowired
    private ObjectProvider<PrototypeBean> prototypeBeanProvider;

    public void doWork() {
        PrototypeBean bean = prototypeBeanProvider.getObject(); // каждый раз новый
    }
}

// 2. Через scoped proxy
@Component
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class PrototypeBean { }

// 3. Через lookup method
@Component
public abstract class SingletonService {
    @Lookup
    public abstract PrototypeBean getPrototypeBean();
}

На собеседовании: ключевой вопрос – проблема внедрения prototype в singleton и способы её решения. Частая ошибка – не знать, что по умолчанию scope – singleton, и не понимать последствия внедрения prototype в singleton.