Spring'in Java Config'ini kullanarak, yalnızca çalışma zamanında elde edilebilen yapıcı argümanları ile prototip kapsamlı bir bean edinmem / başlatmam gerekiyor. Aşağıdaki kod örneğini göz önünde bulundurun (kısalık açısından basitleştirilmiş):
@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 sınıfı aşağıdaki gibi tanımlanır:
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;
}
}
Uyarı name
olduğunu final
sadece bir yapıcı yoluyla sağlanabilir ve değişmezliğini garanti. Diğer bağımlılıklar, Thing
sınıfın uygulamaya özgü bağımlılıklarıdır ve istek işleyici uygulamasının bilinmemesi (sıkı bir şekilde bağlanması) gerekir.
Bu kod, Spring XML yapılandırmasıyla mükemmel şekilde çalışır, örneğin:
<bean id="thing", class="com.whatever.Thing" scope="prototype">
<!-- other post-instantiation properties omitted -->
</bean>
Java yapılandırmasıyla aynı şeyi nasıl başarırım? Aşağıdakiler Spring 3.x kullanıldığında çalışmaz:
@Bean
@Scope("prototype")
public Thing thing(String name) {
return new Thing(name);
}
Şimdi, olabilir bir Fabrikası, örneğin oluşturun:
public interface ThingFactory {
public Thing createThing(String name);
}
Ancak bu , bu kullanım durumu için ideal olan ServiceLocator ve Factory tasarım modelini değiştirmek için Spring'i kullanmanın tüm amacını ortadan kaldırır .
Spring Java Config bunu yapabilseydi, şunlardan kaçınabilirdim:
- Fabrika arayüzünü tanımlama
- Fabrika uygulamasını tanımlama
- Fabrika uygulaması için yazma testleri
Bu, Spring'in zaten XML yapılandırması aracılığıyla desteklediği çok önemsiz bir şey için (nispeten konuşursak) bir ton çalışma.
Thing
uygulama aslında daha karmaşık ve diğer çekirdeklere bağımlılıkları var (kısalık için onları atladım). Bu nedenle, İstek işleyici uygulamasının onlar hakkında bilgi sahibi olmasını istemiyorum çünkü bu, işleyiciyi ihtiyaç duymadığı API'lere / fasulye'lere sıkıca bağlayacaktır. Soruyu (mükemmel) sorunuzu yansıtacak şekilde güncelleyeceğim.
@Qualifier
bir ayarlayıcıya parametreler koyabileceğinizi biliyorum @Autowired
.
@Bean
eserlerle olan örneğiniz . @Bean
Yöntemi geçirilen uygun argümanlarla çağrılan getBean(..)
.