Может ли Spring-бин одновременно иметь scope Singleton и Prototype?

«Может ли Spring-бин одновременно иметь scope Singleton и Prototype?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет, один бин не может иметь две области видимости (scopes) одновременно. По умолчанию бин — Singleton. Аннотация @Scope определяет одну область видимости для бина.

Однако можно создать иллюзию, что синглтон предоставляет prototype-экземпляры, используя проксирование или специальные провайдеры.

1. Использование ScopedProxyMode.TARGET_CLASS При внедрении такого бина Spring внедряет прокси, который при каждом обращении создает новый экземпляр.

@Service
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class PrototypeService {
    // Логика сервиса
}

@Component
public class SingletonClient {
    @Autowired
    private PrototypeService prototypeService; // На самом деле здесь прокси

    public void doWork() {
        // Каждый вызов prototypeService.getSomething() может работать с новым экземпляром,
        // если методы не закэшированы прокси.
    }
}

2. Использование ObjectProvider или Provider (рекомендуемый способ) Это позволяет синглтону явно запрашивать новый экземпляр prototype-бина при необходимости.

@Component
public class SingletonClient {
    @Autowired
    private ObjectProvider<PrototypeService> prototypeServiceProvider;

    public void doWork() {
        PrototypeService newInstance = prototypeServiceProvider.getObject();
        // Используем новый экземпляр
    }
}

Итог: Сам бин имеет одну область видимости, но синглтон может получать новые экземпляры prototype-бина через механизмы Spring.