Ответ
Да, можно, но требуется особая настройка, так как по умолчанию зависимости singleton-бина инжектируются один раз при его создании.
Проблема: Если prototype-бин внедряется в singleton-бин обычным способом (@Autowired), контейнер Spring внедрит его единожды при инициализации singleton-а. В результате singleton будет повторно использовать один и тот же экземпляр prototype-бина, что противоречит его природе.
Решение: Для получения нового экземпляра prototype-бина при каждом обращении необходимо использовать Lookup Method Injection или @Scope("prototype") с proxyMode.
-
@Lookup(аннотация на метод) - предпочтительный способ для Java-конфигурации:@Component @Scope("singleton") public class SingletonService { // Метод, который будет переопределен контейнером @Lookup public PrototypeBean getPrototypeBean() { return null; // Реализация предоставляется Spring } public void doWork() { PrototypeBean bean = getPrototypeBean(); // Каждый вызов возвращает НОВЫЙ экземпляр bean.process(); } } @Component @Scope("prototype") public class PrototypeBean { /* ... */ } -
Использование
ObjectFactoryилиProvider(более гибкий и явный способ):@Component @Scope("singleton") public class SingletonService { @Autowired private ObjectFactory<PrototypeBean> prototypeBeanFactory; // или private Provider<PrototypeBean> prototypeBeanProvider; public void doWork() { PrototypeBean bean = prototypeBeanFactory.getObject(); // Новый экземпляр при каждом getObject() // PrototypeBean bean = prototypeBeanProvider.get(); bean.process(); } }
Вывод: Внедрение возможно, но для корректной работы prototype-бина требуется использовать один из механизмов отложенного получения (@Lookup, ObjectFactory, Provider).