2012-02-28 23 views
7

Tôi muốn tạo hai bean của cùng một lớp thông qua tệp cấu hình xml. Lớp học có một bộ đặt chú thích được điền vào bởi mùa xuân. Trong một trong các định nghĩa bean, tôi cũng cung cấp giá trị theo cách thủ công để ghi đè một từ chú thích. Nhưng khi tôi làm điều này, mùa xuân không còn xử lý dây chú thích.Tự động không xảy ra nếu có một bean khác cùng lớp với thuộc tính được đặt thủ công

Dưới đây là một mã tối thiểu để chứng minh hiệu ứng này, sử dụng @Value vì đơn giản nhưng nó giống với @Autowired:

import org.springframework.beans.factory.annotation.Value; 

import javax.annotation.PostConstruct; 

public class AutowireTest { 
    public String testField; 

    @PostConstruct 
    public void init() { 
    if (testField == null) 
     throw new RuntimeException("FAIL"); 
    } 

    @Value("default") 
    public void setTestField(String testField) { 
    this.testField = testField; 
    } 
} 

và mùa xuân config:

<bean id="au_test1" class="AutowireTest"> 
    <property name="testField" value="manual"/> 
</bean> 

<bean id="au_test2" class="AutowireTest"/> 

Nếu tôi loại bỏ <property name="testField" value="manual"/>, cả đậu nhận "mặc định". Nếu nó có đậu thứ hai ném một ngoại lệ. Tôi đã xem xét mã mùa xuân và AutowiredAnnotationBeanPostProcessor đang sử dụng injectionMetadataCache trong đó lớp là khóa cho siêu dữ liệu tiêm nghĩa là thiết lập thuộc tính cụ thể cho một bean vô hiệu hóa tự động cho các phiên bản khác.

Bất kỳ ý tưởng nào về cách này theo cách này? Làm thế nào tôi có thể đạt được một hiệu ứng tương tự làm việc không nhất thiết cho các giá trị chuỗi mà còn cho các đối tượng đậu?

EDIT: Tôi muốn có thuộc tính có nhiều ứng viên phù hợp. Một được đánh dấu là primary. Trừ khi tôi chỉ định một ứng viên thủ công thông qua xml, tôi muốn có một ứng dụng chính có dây. Cách tiếp cận ban đầu của tôi là sử dụng @Autowired cho thuộc tính này nhưng vì điều này không có tác dụng, tôi đang tìm kiếm giải pháp thay thế. Đối với một số lý do tôi không muốn sử dụng thừa kế bean.

EDIT2: Nếu tôi trao đổi hai định nghĩa bean này, sự cố không xảy ra. Các tài sản được autowired tốt cho đến khi ghi đè thủ công được phát hiện lần đầu tiên. Điều này có nghĩa đây không phải là một tính năng có ý nghĩa vì nó có thể dẫn đến lỗi lạ và khó phát hiện lỗi trong một số dự án có phụ thuộc không dây như mong đợi.

+1

Tôi nghĩ triển khai là cách này để cung cấp hiệu suất tốt hơn. –

+0

Tôi đã gửi nó đến spring jira với một dự án tối thiểu thể hiện vấn đề: https://jira.springsource.org/browse/SPR-9183 – mrembisz

Trả lời

0

Theo tôi đó là một lỗi trong mùa xuân mà tôi đã gửi qua jira. Để giải quyết vấn đề này, chú thích phải được chuyển từ trường setter sang trường. Setter phải ở lại để cho phép ghi đè thủ công tài sản. Logic setter có thể (tôi biết điều này nên tránh) nên được chuyển đến @PostConstruct.Mã ban đầu được chỉnh sửa bên dưới:

import org.springframework.beans.factory.annotation.Value; 

import javax.annotation.PostConstruct; 

public class AutowireTest { 
    @Value("default") 
    public String testField; 

    @PostConstruct 
    public void init() { 
    if (testField == null) 
     throw new RuntimeException("FAIL"); 
    } 

    public void setTestField(String testField) { 
    this.testField = testField; 
    } 
} 
1

Nếu bạn có một cái nhìn tại javadocs cho AutowiredAnnotationBeanPostProcessor, có một lưu ý trong đó nêu:

"tiêm Chú sẽ được thực hiện trước khi tiêm XML, do đó cấu hình sau sẽ ghi đè lên các cựu đối với tài sản có dây thông qua cả hai cách tiếp cận. "

Điều này có nghĩa là thiết lập thuộc tính bean của bạn trong xml và với giá trị thuộc tính cho "testField" tạo ra hai bean mới, trong đó testField được đặt và giá trị rỗng.

Đó là một hoặc một thứ khác. bạn có thể sử dụng autowiring cho một lớp hoặc thiết lập nó theo cách thủ công trong xml nhưng không thể làm cả hai. Tôi đoán rằng khi bạn loại bỏ thuộc tính spring chỉ cần đặt cùng bean autowired cho cả hai tên.

Khi đậu của lớp tương tự được thiết lập bằng tay bạn có thể tiêm chúng vào đậu khác bằng cách sử dụng @Qualifier("au_test1") chú thích

+0

Cảm ơn câu trả lời của bạn. Tôi đã đọc javadoc nhưng tôi không thể thấy nó giải thích những gì tôi quan sát. Ngoài ra tôi đã cập nhật câu hỏi của mình để giải thích những gì tôi muốn đạt được. – mrembisz

+0

Tôi đã thực hiện một cập nhật khác cho câu hỏi của mình, trong đó chỉ ra hành vi này bị ảnh hưởng bởi thứ tự mà đậu được khai báo. Tôi đoán điều đó rõ ràng có nghĩa đây là một lỗi chứ không phải là một tính năng dự định. – mrembisz

Các vấn đề liên quan