Ответ
Spring контейнер управляет полным жизненным циклом только для синглтон-бинов. Для бинов со scope="prototype" контейнер выполняет только инициализацию (вызывает методы @PostConstruct, InitializingBean.afterPropertiesSet()), а затем передаёт экземпляр клиенту.
Причина: Контейнер не отслеживает дальнейшую судьбу prototype-бинов, так как их может быть создано множество, и момент их окончания использования неизвестен. Поэтому финализация (@PreDestroy, DisposableBean.destroy()) не вызывается автоматически.
Решение для очистки ресурсов: Клиентский код, получивший prototype-бин, должен явно вызвать метод очистки, когда бин больше не нужен. Можно использовать ConfigurableBeanFactory.destroyBean().
Пример:
@Scope("prototype")
@Component
public class ExpensiveResourceBean implements DisposableBean {
@Override
public void destroy() {
System.out.println("Освобождение ресурсов prototype-бина");
}
}
@Service
public class ClientService {
@Autowired
private ConfigurableBeanFactory beanFactory;
public void process() {
// Контейнер создает и инициализирует новый бин
ExpensiveResourceBean bean = beanFactory.getBean(ExpensiveResourceBean.class);
try {
// Использование бина
} finally {
// Явный вызов уничтожения для очистки
beanFactory.destroyBean(bean);
}
}
}