Làm thế nào để Spring autowire theo tên khi tìm thấy nhiều hơn một bean phù hợp?


106

Giả sử tôi có các giao diện như sau:

interface Country {}
class USA implements Country {}
class UK implements Country ()

Và đoạn mã cấu hình xml này:

<bean class="USA"/>
<bean id="country" class="UK"/>
<bean id="main" class="Main"/>

Làm cách nào để kiểm soát phần phụ thuộc nào được tự động tải xuống dưới đây? Tôi muốn Vương quốc Anh.

class Main {
    private Country country;
    @Autowired
    public void setCountry(Country country) {
        this.country = country;
    }
}

Tôi đang sử dụng Spring 3.0.3.RELEASE.


Tôi nghĩ rằng tôi sẽ nói thêm rằng tôi đã nhận được một "Không có loại đậu duy nhất thuộc loại ..." trong một môi trường (thử nghiệm) và nó hoạt động tốt trong môi trường phát triển của tôi. Tôi chắc chắn đó là một số loại classpath, nhưng hóa ra, nếu bạn thêm @Qualifier, nó hoạt động tốt.
markthegrea 17/02/12

Câu trả lời:


113

Điều này được ghi lại trong phần 3.9.3 của hướng dẫn sử dụng Spring 3.0:

Đối với đối sánh dự phòng, tên bean được coi là giá trị định tính mặc định.

Nói cách khác, hành vi mặc định giống như thể bạn đã thêm vào @Qualifier("country")phương thức setter.


Khi bạn nói "bean name", bạn có nghĩa là tên của trường sẽ chứa bean? (ví dụ trong trường hợp này country)
Vụ kiện Quỹ Monica

67

Bạn có thể sử dụng chú thích @Qualifier

Từ đây

Tinh chỉnh tính năng tự động phân bổ dựa trên chú thích với các bộ định lượng

Vì tự động phân bổ theo loại có thể dẫn đến nhiều ứng viên, nên thường cần kiểm soát nhiều hơn quá trình lựa chọn. Một cách để thực hiện điều này là sử dụng chú thích @Qualifier của Spring. Điều này cho phép liên kết các giá trị định tính với các đối số cụ thể, thu hẹp tập hợp các loại đối sánh để một bean cụ thể được chọn cho mỗi đối số. Trong trường hợp đơn giản nhất, đây có thể là một giá trị mô tả đơn giản:

class Main {
    private Country country;
    @Autowired
    @Qualifier("country")
    public void setCountry(Country country) {
        this.country = country;
    }
}

Điều này sẽ sử dụng Vương quốc Anh thêm một id vào USA bean và sử dụng nó nếu bạn muốn USA.


12

Một cách khác để đạt được kết quả tương tự là sử dụng chú thích @Value:

public class Main {
     private Country country;

     @Autowired
     public void setCountry(@Value("#{country}") Country country) {
          this.country = country;
     }
}

Trong trường hợp này, "#{country}chuỗi là một biểu thức Ngôn ngữ Biểu thức Mùa xuân (SpEL) được đánh giá là một bean có tên country.


có thể được tiêm dựa trên tài sản? Điều gì sẽ xảy ra nếu Hoa Kỳ hoặc Vương quốc Anh là một số loại tham số đến từ URL và tôi muốn đưa vào 2 thứ khác nhau dựa trên tham số là gì?
Kalpesh Soni

6

Một giải pháp khác với giải quyết theo tên:

@Resource(name="country")

Nó sử dụng gói javax.annotation , vì vậy nó không dành riêng cho Spring, nhưng Spring hỗ trợ nó.


1
nhưng @Resourcesẽ không có mặt ở đó out-of-the-box với java 11 do modul ghép hình
Dirk Hoffmann

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.