Ответ
В Spring контексте область видимости (scope) prototype означает, что контейнер создает новый экземпляр бина при каждом запросе (через getBean() или инъекцию зависимости).
Пример объявления:
@Component
@Scope("prototype")
public class PrototypeService {
private String id = UUID.randomUUID().toString();
public String getId() { return id; }
}
Пример использования:
@Autowired
private ApplicationContext context;
public void demo() {
PrototypeService bean1 = context.getBean(PrototypeService.class);
PrototypeService bean2 = context.getBean(PrototypeService.class);
System.out.println(bean1.getId()); // e.g., "c1b3f7a2..."
System.out.println(bean2.getId()); // ДРУГОЙ ID, e.g., "f8a92e1d..."
System.out.println(bean1 == bean2); // false
}
Ключевые моменты:
- Управление жизненным циклом: Spring создает бин, но не управляет его полным жизненным циклом после передачи клиенту. Уничтожение — ответственность клиента.
- Использование: Подходит для состояния, специфичного для каждого запроса (например, объект корзины покупок в веб-приложении).
- Отличие от
singleton: Область по умолчаниюsingletonсоздает один экземпляр на весь контейнер.
Ответ 18+ 🔞
Ну, слушай, вот есть у тебя в Spring эта вся хуйня с бинами, да? И там, в основном, все живут как синглтоны — один мужик на весь район, и все к нему ходят за водкой. А иногда надо, чтобы на каждого клиента был свой отдельный, свеженький экземпляр. Вот это и есть prototype, ёпта.
Представь, ты в пивнушку зашёл и кричишь: «Дайте мне пива!». Тебе наливают из одной бочки в твой личный стакан. Ты его выпил — стакан помыли или выкинули, похуй. Заходит следующий — ему новый стакан наливают. Вот prototype — это как раз про эти личные стаканы. Новый каждый раз, блядь.
Вот как это объявляется, смотри:
@Component
@Scope("prototype")
public class PrototypeService {
private String id = UUID.randomUUID().toString();
public String getId() { return id; }
}
Видишь, @Scope("prototype") повесили. Это значит, что каждый раз, когда Spring'у скажут «дай-ка сюда PrototypeService», он такой: «Опа, ща, братан!» — и херачит новый объект. ID у каждого будет свой, уникальный, потому что UUID при создании генерится.
А вот как это на практике выглядит:
@Autowired
private ApplicationContext context;
public void demo() {
PrototypeService bean1 = context.getBean(PrototypeService.class);
PrototypeService bean2 = context.getBean(PrototypeService.class);
System.out.println(bean1.getId()); // Например, "c1b3f7a2..."
System.out.println(bean2.getId()); // Совсем ДРУГОЙ ID, "f8a92e1d..."
System.out.println(bean1 == bean2); // false, потому что это два разных стакана, ёпта!
}
А теперь, блядь, важные нюансы, чтоб не обосраться:
- Жизненный цикл — твоя головная боль: Spring, как заботливая мама, создаст тебе бин, передаст в руки и скажет: «Всё, сынок, дальше сам». Уничтожать его, когда он уже не нужен — это твоя забота. Контейнер за прототипами не убирается, как за синглтонами.
- Где это впилить? Идеально для штук, которые живут один запрос. Ну, типа, объект корзины в интернет-магазине. Каждому юзеру — своя корзина, а то получится ебаный коммунизм, все в одну корзину ссут.
- Чем не синглтон? Да тем, блядь, что синглтон — он один, как царь и бог, на весь контейнер. А прототип — как одноразовые тарелки на пикнике: взял, поел, выкинул, взял новый. Никакого общего состояния, никаких неожиданных сюрпризов, когда один чувак нечаянно всем суп пересолол.
Вот и вся магия, ничего сложного. Главное — помни, что за собой надо убирать, а то память засрешь этими прототипами.