พื้นหลัง:
ฉันมีแอปพลิเคชัน Spring 2.5 / Java / Tomcat มีถั่วต่อไปนี้ซึ่งใช้ทั่วทั้งแอปพลิเคชั่นในหลาย ๆ ที่
public class HibernateDeviceDao implements DeviceDao
และถั่วต่อไปนี้ซึ่งเป็นของใหม่:
public class JdbcDeviceDao implements DeviceDao
bean แรกถูกกำหนดค่าให้ดังนั้น (beans ทั้งหมดในแพ็คเกจถูกรวมไว้)
<context:component-scan base-package="com.initech.service.dao.hibernate" />
ถั่วที่สอง (ใหม่) ถูกกำหนดค่าแยกกัน
<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao">
<property name="dataSource" ref="jdbcDataSource">
</bean>
ผลลัพธ์นี้ (แน่นอน) มีข้อยกเว้นเมื่อเริ่มต้นเซิร์ฟเวอร์:
ข้อยกเว้นแบบซ้อนคือ org.springframework.beans.factory.NoSuchBeanDefinitionException: ไม่มีถั่วที่ไม่ซ้ำประเภท [com.sevenp.mobile.samplemgmt.service.dao.DeviceDao] พบถั่วที่จับคู่เดี่ยว แต่พบ 2: [deviceDao, jdbcDeviceDao]
จากคลาสที่พยายาม autowire bean แบบนี้
@Autowired
private DeviceDao hibernateDevicDao;
เนื่องจากมีสองถั่วที่ใช้อินเตอร์เฟสเดียวกัน
คำถาม:
เป็นไปได้ไหมที่จะกำหนดค่า beans เพื่อให้
1.ฉันไม่ต้องทำการเปลี่ยนแปลงคลาสที่มีอยู่ซึ่งมีHibernateDeviceDao
autowired อยู่แล้ว
2.ยังคงสามารถใช้ถั่วที่สอง (ใหม่) เช่นนี้:
@Autowired
@Qualifier("jdbcDeviceDao")
นั่นคือฉันจะต้องมีวิธีการกำหนดค่าHibernateDeviceDao
ถั่วเป็นถั่วเริ่มต้นให้เป็นแบบอัตโนมัติพร้อมกันทำให้การใช้งานของJdbcDeviceDao
เมื่อระบุอย่างชัดเจนด้วย@Qualifier
คำอธิบายประกอบ
สิ่งที่ฉันได้ลองไปแล้ว:
ฉันลองตั้งค่าคุณสมบัติ
autowire-candidate="false"
ในการกำหนดค่า bean สำหรับ JdbcDeviceDao:
<bean id="jdbcDeviceDao" class="com.initech.service.dao.jdbc.JdbcDeviceDao" autowire-candidate="false">
<property name="dataSource" ref="jdbcDataSource"/>
</bean>
เพราะเอกสาร Spring บอกว่า
บ่งชี้ว่าควรพิจารณาว่า bean นี้หรือไม่เมื่อค้นหาผู้สมัครที่ตรงกันเพื่อตอบสนองความต้องการในการเข้าร่วมของถั่วอื่น โปรดทราบว่าสิ่งนี้จะไม่ส่งผลกระทบต่อการอ้างอิงที่ชัดเจนโดยใช้ชื่อซึ่งจะได้รับการแก้ไขแม้ว่าถั่วที่ระบุจะไม่ถูกทำเครื่องหมายเป็นตัวเลือกตอบรับอัตโนมัติ *
ซึ่งฉันตีความว่าหมายความว่าฉันยังสามารถ autowire JdbcDeviceDao
โดยใช้@Qualifier
คำอธิบายประกอบและมีHibernateDeviceDao
ถั่วเป็นค่าเริ่มต้น เห็นได้ชัดว่าการตีความของฉันไม่ถูกต้อง แต่เนื่องจากผลลัพธ์ในข้อความแสดงข้อผิดพลาดต่อไปนี้เมื่อเริ่มต้นเซิร์ฟเวอร์:
ไม่พอใจการพึ่งพาประเภท [class com.sevenp.mobile.samplemgmt.service.dao.jdbc.JdbcDeviceDao]: คาดว่าจะมีถั่วที่ตรงกันอย่างน้อย 1 ตัว
มาจากชั้นเรียนที่ฉันลอง autowiring bean พร้อมกับ qualifier:
@Autowired
@Qualifier("jdbcDeviceDao")
สารละลาย:
คำแนะนำของ skaffmanเพื่อลองใช้คำอธิบายประกอบ @Resource ดังนั้นการกำหนดค่ามีการตั้งค่าผู้สมัคร autowire เป็นเท็จสำหรับ jdbcDeviceDao และเมื่อใช้ jdbcDeviceDao ฉันอ้างถึงมันโดยใช้คำอธิบายประกอบ @Resource (แทน @Qualifier):
@Resource(name = "jdbcDeviceDao")
private JdbcDeviceListItemDao jdbcDeviceDao;