Уничтожается ли Spring-бин со scope ‘prototype’ сразу после инъекции в другой бин?

«Уничтожается ли Spring-бин со scope ‘prototype’ сразу после инъекции в другой бин?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Нет, бин со scope prototype не уничтожается Spring-контейнером автоматически сразу после инъекции.

Ключевое поведение бина prototype:

  • Создание: Контейнер Spring создает новый экземпляр каждый раз, когда запрашивается этот бин (через getBean() или при инъекции в другой бин).
  • Жизненный цикл: Spring отвечает только за создание и настройку (инициализацию) prototype-бина. Контейнер НЕ управляет его полным жизненным циклом — он не вызывает метод @PreDestroy и не выполняет последующую очистку.
  • Ответственность за уничтожение: Освобождение ресурсов (закрытие соединений, файлов и т.д.) ложится на клиентский код, который получил этот бин.

Практический пример:

@Component
@Scope("prototype")
public class PrototypeService {
    private String id = UUID.randomUUID().toString();
    @PreDestroy
    public void cleanup() {
        System.out.println("Cleaning up " + id); // ЭТОТ МЕТОД НЕ БУДЕТ ВЫЗВАН КОНТЕЙНЕРОМ!
    }
    public String getId() { return id; }
}

@Component
public class SingletonClient {
    @Autowired
    private PrototypeService prototypeService; // Здесь внедряется НОВЫЙ экземпляр

    public void printId() {
        System.out.println(prototypeService.getId());
    }
    // Когда SingletonClient уничтожается, внедренный PrototypeService НЕ уничтожается автоматически.
}

Важный вывод: Используйте scope prototype для состояния, которое не должно разделяться, но помните, что управление памятью и ресурсами становится вашей ответственностью. Для ресурсов, требующих явного освобождения, реализуйте собственный метод закрытия и вызывайте его вручную.