Menggunakan Spring's Java Config, saya perlu mendapatkan / membuat contoh prototipe-scoped bean dengan argumen konstruktor yang hanya dapat diperoleh saat runtime. Pertimbangkan contoh kode berikut (disederhanakan untuk singkatnya):
@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
}
di mana kelas Thing didefinisikan sebagai berikut:
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;
}
}
Perhatikan name
adalah final
: itu hanya dapat diberikan melalui konstruktor, dan menjamin keabadian. Ketergantungan lain adalah dependensi implementasi-spesifik dari Thing
kelas, dan tidak boleh diketahui (digabungkan erat dengan) implementasi penangan permintaan.
Kode ini berfungsi dengan baik dengan konfigurasi Spring XML, misalnya:
<bean id="thing", class="com.whatever.Thing" scope="prototype">
<!-- other post-instantiation properties omitted -->
</bean>
Bagaimana cara mencapai hal yang sama dengan konfigurasi Java? Berikut ini tidak berfungsi menggunakan Spring 3.x:
@Bean
@Scope("prototype")
public Thing thing(String name) {
return new Thing(name);
}
Sekarang, saya dapat membuat Pabrik, misalnya:
public interface ThingFactory {
public Thing createThing(String name);
}
Tapi itu mengalahkan seluruh titik menggunakan Spring untuk mengganti pola desain ServiceLocator dan Factory , yang akan ideal untuk use case ini.
Jika Spring Java Config dapat melakukan ini, saya akan dapat menghindari:
- mendefinisikan antarmuka pabrik
- mendefinisikan implementasi Pabrik
- tes tertulis untuk implementasi Pabrik
Itu satu ton pekerjaan (relatif berbicara) untuk sesuatu yang sangat sepele bahwa Spring sudah mendukung melalui konfigurasi XML.
Thing
implementasi sebenarnya lebih kompleks dan memang memiliki ketergantungan pada kacang lainnya (saya hanya menghilangkannya untuk singkatnya). Karena itu, saya tidak ingin implementasi Request handler tahu tentang mereka, karena ini akan secara ketat memasangkan handler ke API / kacang yang tidak perlu. Saya akan memperbarui pertanyaan untuk mencerminkan pertanyaan Anda (luar biasa).
@Qualifier
parameter ke setter dengan @Autowired
setter itu sendiri.
@Bean
karya. The @Bean
Metode dipanggil dengan argumen yang tepat Anda dilewatkan ke getBean(..)
.