Используя Spring Java Config, мне нужно получить/создать экземпляр bean-объекта с прототипом с аргументами конструктора, которые доступны только во время выполнения. Рассмотрим следующий пример кода (упрощенно для краткости):
@Autowired
private ApplicationContext appCtx;
public void onRequest(Request request) {
//request is already validated
String name = request.getParameter("name");
Thing thing = appCtx.getBean(Thing.class, name);
//System.out.println(thing.getName()); //prints name
}
где класс Thing определяется следующим образом:
public class Thing {
private final String name;
@Autowired
private SomeComponent someComponent;
@Autowired
private AnotherComponent anotherComponent;
public Thing(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
name
уведомления является final
: оно может быть предоставлено только через конструктор и гарантирует неизменность. Другие зависимости являются зависимыми от реализации зависимостями класса Thing
и не должны быть известны (тесно связаны) с реализацией обработчика запросов.
Этот код прекрасно работает с конфигурацией Spring XML, например:
<bean id="thing", class="com.whatever.Thing" scope="prototype">
<!-- other post-instantiation properties omitted -->
</bean>
Как мне добиться того же с помощью конфигурации Java? Следующее не работает с использованием Spring 3.x:
@Bean
@Scope("prototype")
public Thing thing(String name) {
return new Thing(name);
}
Теперь я могу создать Фабрику, например:
public interface ThingFactory {
public Thing createThing(String name);
}
Но это сводит на нет весь смысл использования Spring для замены шаблона проектирования ServiceLocator и Factory, что было бы идеально для этого варианта использования.
Если бы Spring Java Config мог это сделать, я бы смог избежать:
- определение фабричного интерфейса
- определение реализации Factory
- написание тестов для реализации Factory
Это тонна работы (условно говоря) для чего-то настолько тривиального, что Spring уже поддерживает через XML-конфигурацию.