JavaRush /Курсы /Модуль 5. Spring /Области видимости Singleton и Prototype в Spring

Области видимости Singleton и Prototype в Spring

Модуль 5. Spring
3 уровень , 10 лекция
Открыта

Область видимости singleton

Управление осуществляется только одним общим экземпляром бина-одиночки, а все запросы к бинам с идентификатором или идентификаторами, соответствующими определению этого бина, приводят к тому, что контейнер Spring возвращает именно этот экземпляр бина.

Иными словами, когда вы назначаете определение бина и он входит в область видимости singleton, IoC-контейнер Spring создает ровно один экземпляр объекта, назначенного этим определением бина. Этот единственный экземпляр хранится в кэше таких бинов-одиночек, а все последующие запросы и ссылки на этот именованный бин возвращают кэшированный объект. На следующем изображении показано, как работает область видимости singleton:

Понятие бина-одиночки в Spring отличается от понятия шаблона-одиночки, определенного в книге о шаблонах "Банды четырёх" (Gang of Four/GoF). В случае объекта-одиночки GoF область видимости объекта жестко кодируется таким образом, что для каждого ClassLoader создается один и только один экземпляр конкретного класса. Область видимости одиночки в Spring лучше всего описать как per-container и per-bean. Это означает, что если вы определяете один бина для конкретного класса в одном контейнере Spring, контейнер Spring создает один и только один экземпляр класса, заданного этим определением бина. Область видимости singleton - это область видимости Spring по умолчанию. Чтобы определить бин как объект-одиночку в XML, вы можете определить бина способом, показанным в следующем примере:

<bean id="accountService" class="com.something.DefaultAccountService"/>
<!-- следующее эквивалентно, хотя и избыточно (по умолчанию используется область видимости singleton) -->
<bean id="accountService" class="com.something.DefaultAccountService" scope="singleton"/>

Область видимости prototype

Не-singleton область видимости prototype для развертывания бина создает новый экземпляр бина каждый раз, когда выполняется запрос на этот конкретный бин. То есть бин внедряется в другой бин или запрашивается через вызов метода getBean() в контейнере. Как правило, следует использовать область видимости prototype для всех бинов, сохраняющих состояние, и область видимости singleton для бинов, не сохраняющих состояние.

Следующая схема иллюстрирует область видимости prototype в Spring:

(Объект доступа к данным (DAO) обычно не конфигурируется как прототип, потому что типичный DAO не сохраняет никакого диалогового состояния. Было проще повторно использовать ядро схемы для объекта-одиночки).

В следующем примере бин определяется как прототип в XML:

<bean id="accountService" class="com.something.DefaultAccountService" scope="prototype"/>

В отличие от других областей видимости, Spring не управляет полным жизненным циклом бина-прототипа. Контейнер создает экземпляр, конфигурирует и иным образом компонует объект-прототип и передает его клиенту, без дальнейших записей об этом экземпляре прототипа. Таким образом, хотя методы обратного вызова жизненного цикла инициализации вызываются для всех объектов независимо от области видимости, в случае прототипов, сконфигурированные обратные вызовы жизненного цикла разрушения не вызываются. Клиентский код должен подчищать объекты, входящие в область видимости prototype, и высвободить ценные ресурсы, которые потребляют бины-прототипы. Чтобы заставить контейнер Spring высвободить ресурсы, потребляемые бинами, входящими в область видимости prototype, попробуйте использовать специальный постпроцессор бинов, содержащий ссылку на бины, которые необходимо подчистить.

В некотором смысле роль контейнера Spring в отношении бинов, входящих в область видимости prototype, является заменой оператора Java new. Все управление жизненным циклом после данного момента должно осуществляться с клиентской стороны. (Подробнее о жизненном цикле бина в контейнере Spring см. в разделе Обратные вызовы жизненного цикла).

Бины-одиночки с зависимостями прототип-бин

Если вы используете бины, находящиеся в области видимости singleton, и с зависимостью от бинов-прототипов, помните, что зависимости разрешаются при создании экземпляра. Таким образом, если внедрять зависимость от бина-прототипа в бин, находящийся в области видимости singleton, создается экземпляр нового бина-прототипа, а затем внедряется в бин-одиночку. Экземпляр прототипа - это единственный экземпляр, который предоставляется бину, находящемуся в области видимости singleton.

Однако, предположим, вам нужно, чтобы бин, находящийся в области видимости singleton, неоднократно получал новый экземпляр бина, находящегося в области видимости prototype, во время выполнения. У вас не получится внедрить зависимость от бина, находяшегося в области видимости prototype, в ваш бин-одиночку, потому что внедрение происходит только один раз, когда контейнер Spring создает экземпляр бина-одиночки, разрешает и внедряет его зависимости.

Комментарии (5)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Olexandr Уровень 47
13 мая 2025
"У вас не получится внедрить зависимость от бина, находяшегося в области видимости prototype, в ваш бин-одиночку, потому что внедрение происходит только один раз, когда контейнер Spring создает экземпляр бина-одиночки, разрешает и внедряет его зависимости." - получится, но советую погуглить - как - потому что иногда спрашивают. (Ответ - аннотация @LookUp , Object Provider или же получать зависимость прямо из контекста)
СтудентJava Уровень 109
29 марта 2025
Смысл статей без практики?! То что я прочитал, это все документация переведенная. А чем закреплять?!
Artem I Уровень 106
6 июля 2025
Такая же ерунда, статьи настолько оторваны от жизни, что я даже не понимаю, какую задачу пытались решить. Для какой задачи создали этот инструмент. Выучить без понимания проблематики нереально.
Андрей Уровень 109
28 августа 2024
стааь лайк если передумал учить джаву но уже поздно)
И. Ж. Уровень 41
30 июля 2024
Комментарии выдохлись, метериал демотивировал, истощил желающих от лекции к лекции..