ด้วยการใช้ Java Config ของ Spring ฉันจำเป็นต้องได้รับ / สร้างอินสแตนซ์ถั่วที่กำหนดขอบเขตต้นแบบด้วยอาร์กิวเมนต์ตัวสร้างที่หาได้ในรันไทม์เท่านั้น พิจารณาตัวอย่างโค้ดต่อไปนี้ (ย่อให้สั้นลง):
@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 config ตัวอย่างเช่น:
<bean id="thing", class="com.whatever.Thing" scope="prototype">
<!-- other post-instantiation properties omitted -->
</bean>
ฉันจะบรรลุสิ่งเดียวกันกับ Java config ได้อย่างไร สิ่งต่อไปนี้ใช้ไม่ได้กับ 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 สามารถทำได้ฉันจะสามารถหลีกเลี่ยง:
- การกำหนดอินเทอร์เฟซจากโรงงาน
- การกำหนดการใช้งานจากโรงงาน
- การทดสอบการเขียนสำหรับการใช้งานในโรงงาน
นั่นเป็นงานมากมาย (ค่อนข้างพูด) สำหรับบางสิ่งที่ไม่สำคัญซึ่ง Spring รองรับผ่านการกำหนดค่า XML แล้ว
Thing
ใช้งานนั้นซับซ้อนกว่าและมีการพึ่งพาถั่วอื่น ๆ (ฉันแค่ละไว้เพื่อความกะทัดรัด) ด้วยเหตุนี้ฉันไม่ต้องการให้การใช้งานตัวจัดการคำขอทราบเกี่ยวกับสิ่งเหล่านี้เนื่องจากจะเป็นการจับคู่ตัวจัดการกับ API / ถั่วที่ไม่จำเป็นอย่างแน่นหนา ฉันจะอัปเดตคำถามเพื่อให้สอดคล้องกับคำถาม (ยอดเยี่ยม) ของคุณ
@Qualifier
พารามิเตอร์ให้กับตัวตั้งค่าด้วย@Autowired
ตัวเซ็ตเตอร์เอง
@Bean
ผลงาน วิธีการได้รับเรียกว่ามีข้อโต้แย้งที่เหมาะสมที่คุณส่งผ่านไปยัง@Bean
getBean(..)