Korzystając z Java Config Springa, muszę uzyskać / utworzyć komponent bean o zakresie prototypu z argumentami konstruktora, które są dostępne tylko w czasie wykonywania. Rozważmy następujący przykład kodu (uproszczony dla zwięzłości):
@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
}
gdzie klasa Thing jest zdefiniowana w następujący sposób:
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;
}
}
Wskazówka name
jest final
: może być dostarczone tylko przez konstruktora i gwarantuje niezmienność. Inne zależności są zależnościami Thing
klasy specyficznymi dla implementacji i nie powinny być znane (ściśle powiązane) z implementacją programu obsługi żądań.
Ten kod działa doskonale z konfiguracją Spring XML, na przykład:
<bean id="thing", class="com.whatever.Thing" scope="prototype">
<!-- other post-instantiation properties omitted -->
</bean>
Jak osiągnąć to samo dzięki konfiguracji Java? Następujące elementy nie działają w Spring 3.x:
@Bean
@Scope("prototype")
public Thing thing(String name) {
return new Thing(name);
}
Teraz mógłbym stworzyć Factory np:
public interface ThingFactory {
public Thing createThing(String name);
}
Ale to podważa cały sens używania Springa do zastąpienia wzorca projektowego ServiceLocator i Factory , który byłby idealny w tym przypadku użycia.
Gdyby Spring Java Config mógł to zrobić, byłbym w stanie uniknąć:
- definiowanie interfejsu Factory
- definiowanie implementacji Factory
- pisanie testów na wdrożenie Factory
To mnóstwo pracy (względnie mówiąc) na coś tak trywialnego, że Spring obsługuje już konfigurację XML.