DEV Community

Cover image for Волшебные скоупы: Как Spring организует работу бинов
Olga Lugacheva
Olga Lugacheva

Posted on

Волшебные скоупы: Как Spring организует работу бинов

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

Чтобы работа мастерской была упорядоченной и эффективной, для бинов были установлены четкие правила — скоупы. Эти правила определяли, как долго бины могли существовать и сколько экземпляров одного вида должно быть создано одновременно. Благодаря этим волшебным рамкам мастерская работала слаженно и надежно.

Прототип (Prototype): Ежик-пекарь

hedgehog
Ежик-пекарь каждый раз, когда кто-то заказывает пирог, создает новый пирог с уникальными ингредиентами.

Ежик: "Каждый хочет свой вкус! Поэтому я создаю свежий пирог для каждого заказа."

@Component
@Scope("prototype")
public class Hedgehog {
    public void bakePie() {
        System.out.println("Пеку пирог!");
    }
}

Enter fullscreen mode Exit fullscreen mode

Так работает scope prototype в Spring: каждый раз при запросе нового объекта создается уникальный экземпляр бина. Это полезно, когда требуется изолированная логика для каждого использования.

Например:

В приложении есть бин, который генерирует отчет для каждого пользователя:

@Component
@Scope("prototype")
public class ReportGenerator {
    public Report generate(String userData) {
        // Генерация уникального отчета
        return new Report(userData);
    }
}

Enter fullscreen mode Exit fullscreen mode

Каждый вызов context.getBean(ReportGenerator.class) создаст новый экземпляр. Это удобно для обработки уникальных данных в многопользовательских системах.


Request: Кролик-раздатчик морковки

rbt
Кролик-раздатчик объясняет своим помощникам:

"Для каждого гостя, который приходит на поляну, я собираю морковку. Но как только гость уходит, корзинка возвращается ко мне."

@Component
@Scope("request")
public class Rabbit {
    public void giveCarrot() {
        System.out.println("Вот твоя морковка!");
    }
}

Enter fullscreen mode Exit fullscreen mode

Request scope в Spring означает, что один бин создается на каждый HTTP-запрос. После завершения запроса бин уничтожается.

Пример использования:
Представьте, что в веб-приложении у вас есть компонент для сбора данных пользователя:

@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserCart {
    private List<Item> items = new ArrayList<>();

    public void addItem(Item item) {
        items.add(item);
    }

    public List<Item> getItems() {
        return items;
    }
}

Enter fullscreen mode Exit fullscreen mode

Каждому запросу пользователя выделяется уникальная корзина, которая "живёт" только в рамках обработки HTTP-запроса. Как только запрос завершён, бин удаляется, освобождая память.

Сравнение Prototype и Request в реальной разработке:

Prototype: используется для задач, требующих уникальных экземпляров при каждом вызове, например, в тестировании, генерации уникальных данных, обработки изолированных задач.
Request: полезен в веб-приложениях для обеспечения изоляции данных между запросами пользователей. Например, корзина покупок, данные аутентификации или временные токены.
Разница в подходах:

Prototype может использоваться в любых контекстах, включая консольные приложения.
Request строго привязан к веб-контексту, поскольку зависит от HTTP-запросов.


Singleton: Боб-строитель

woodchuck
Боб-строитель работает в лесу и строит плотину для всех. Он говорит:

"Я один, и я построю что угодно, сколько бы животных ко мне ни пришло!"

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

@Component
@Scope("singleton")
public class Bob {
    public void buildDam() {
        System.out.println("Строю плотину!");
    }
}

Enter fullscreen mode Exit fullscreen mode

Singleton — это скоуп по умолчанию в Spring. Один экземпляр бина создается на всё время работы приложения. Такой бин используется, когда объект должен быть общим ресурсом для всех компонентов приложения.

Пример использования:
Предположим, у вас есть компонент для логирования:

@Component
public class Logger {
    public void log(String message) {
        System.out.println(message);
    }
}

Enter fullscreen mode Exit fullscreen mode

Этот бин создается один раз, и все компоненты приложения используют его для записи логов. Это эффективно и экономит память.

Применение:

  • Логирование
  • Работа с базой данных через пул соединений
  • Управление кэшами

Session: Медвежонок Мед

bear
Медвежонок варит мед для каждого гостя, который пришел в его дом. Он говорит:

"Пока ты у меня в гостях, я заботюсь о твоем горшочке. Но как только ты уходишь, твой медовый горшочек исчезает."

@Component
@Scope("session")
public class Bear {
    public void makeHoney() {
        System.out.println("Варю мед для тебя!");
    }
}

Enter fullscreen mode Exit fullscreen mode

Скоуп session в Spring означает, что бин существует столько, сколько длится HTTP-сессия пользователя.

Техническое пояснение:
Этот скоуп используется в веб-приложениях, чтобы привязать объект к конкретной сессии пользователя. Когда сессия завершается, бин уничтожается.

Пример использования:
Представьте, что у вас есть компонент для хранения данных авторизации пользователя:

@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserSession {
    private String userId;

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUserId() {
        return userId;
    }
}

Enter fullscreen mode Exit fullscreen mode

Этот бин создается для каждого пользователя, пока длится его сессия.

Применение:

  • Хранение данных пользователя (например, авторизации, предпочтений)
  • Управление сессионными токенами

Application: Филин Фил

Филин Фил каждый вечер рассказывает сказки всем лесным жителям. Он говорит:

"Моя сказка одна на весь лес. Все приходят ко мне слушать, и всем хватает!"

@Component
@Scope("application")
public class Owl {
    public void shareWisdom() {
        System.out.println("Мудрость дня: бобры строят лучшие плотины.");
    }
}

Enter fullscreen mode Exit fullscreen mode

Скоуп application означает, что бин создается один раз на всё приложение, но отличается от singleton тем, что он используется только в контексте веб-приложений.

Этот скоуп аналогичен singleton, но управляется веб-контекстом. Он используется для компонентов, которые должны быть доступны на уровне всего приложения.

Пример использования:
Например, бин для хранения глобальных настроек:

@Component
@Scope(value = WebApplicationContext.SCOPE_APPLICATION)
public class AppSettings {
    private String appName = "ForestApp";

    public String getAppName() {
        return appName;
    }
}

Enter fullscreen mode Exit fullscreen mode

Этот бин создается один раз и доступен всем.

Применение:

  • Конфигурация приложения
  • Глобальные настройки
  • Кэш данных, общий для всех пользователей

Сравнение всех скоупов Spring

Scope Жизненный цикл Пример использования
Singleton Всё время работы приложения Логирование, работа с базами данных
Prototype Новый объект при каждом вызове Генерация отчётов, тестирование
Request Один HTTP-запрос Корзина покупок, временные данные
Session Вся HTTP-сессия пользователя Данные авторизации, настройки пользователя
Application Всё время работы приложения Глобальные настройки, кэш на уровне приложения

Когда что использовать?
Singleton — для общих, не изменяющихся ресурсов.
Prototype — для изолированных задач, уникальных данных.
Request — для временных данных в рамках одного запроса.
Session — для данных, которые нужно хранить между запросами одного пользователя.
Application — для глобальных данных, которые используют все пользователи.

Image of Timescale

Timescale – the developer's data platform for modern apps, built on PostgreSQL

Timescale Cloud is PostgreSQL optimized for speed, scale, and performance. Over 3 million IoT, AI, crypto, and dev tool apps are powered by Timescale. Try it free today! No credit card required.

Try free

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay