2012-05-10 13 views
19

Trong CDI bạn có thể xác định một đối tượng mà sẽ cung cấp cho bạn các mặt hàng của một loại nhất định, sử dụng là gì:tương đương với mùa xuân cho Instance CDI, hoặc cung cấp Guices

 
@Inject 
Instance<MyObject> myObjectInstance; 
//... 
MyObject myObjectInstance.get(); 

Tương tự như vậy trong Guice bạn có thể làm:

 
@Inject 
Provider<MyObject> myObjectInstance; 
//... 
MyObject myObjectInstance.get(); 

tôi tự hỏi nếu có một cấu trúc tương tự như trong mùa xuân, hoặc bạn phải sử dụng ApplicationContext để có được những tài liệu tham khảo?

Trả lời

15

Vì vậy, sau rất nhiều đào bới xung quanh tôi phát hiện ra rằng mùa xuân hỗ trợ JSR-330. JSR này định nghĩa một API đơn giản - toàn bộ thông số là nghĩa đen chỉ là API này - tiêu chuẩn hóa một số giao diện tiêm phụ thuộc, chú thích và hành vi.

Không giống như giao diện FactoryBean của Spring javax.inject.Provider không ném Ngoại lệ khi nhận tham chiếu bean. Hơn nữa, bạn vẫn sẽ cần phải xác định FactoryBean này ở một số nơi (đọc XML, hoặc @Configuration lớp, và điều này là tối ưu).

Do lỗi, trong mùa xuân hiện tại 3.1.1, javax.inject.Provider không hoạt động. Nó không hoạt động trong Mùa xuân 3.1.0.

Để sử dụng nó, bạn đơn giản cần phải bao gồm jar javax.inject - nếu bạn sử dụng maven bạn có thể:

<dependency> 
     <groupId>javax.inject</groupId> 
     <artifactId>javax.inject</artifactId> 
     <version>1</version> 
    </dependency> 

mùa xuân sẽ phát hiện nó, và từ thời điểm đó trên bạn có thể chỉ đơn giản là:

@Inject 
Provider<MyObject> myObjectInstance; 
//... 
MyObject myObjectInstance.get(); 

như trong ví dụ Guice, vì đó là cùng một API.

Mặc dù nhận xét trước đó của tôi đối với Konstantin, Spring tự tạo Nhà cung cấp. (Tôi đã thử nghiệm nó chống lại mùa xuân 3.1.1 và chạy vào đây Spring Provider regression issue)

+0

+1 Câu trả lời hay. –

+1

Tôi lo ngại có sự khác biệt đáng kể giữa Nhà cung cấp <> và Instance <> (hy vọng tôi sai). Thứ nhất: Instance triển khai Iterable và điều này có tác động lớn đến cách bạn sử dụng nó. Ví dụ. sử dụng thường xuyên cho tôi là khai báo @Inject Instance xxx ... vì vậy tôi sẽ có thể lặp qua các phiên bản của mỗi lớp thực hiện giao diện mà không biết classname. Tôi sẽ muốn biết làm thế nào để làm điều này bằng cách sử dụng nhà cung cấp. – Rafael

+0

'Instance <>' không phải là một phần của JSR-330, và cũng không phải là một phần của Spring. Các vấn đề mà tôi đã có lúc đó là để có được đậu nguyên mẫu (mà phụ thuộc vào một số biến ngữ cảnh) mà không nhận được một tổ chức trên applicationContext chính nó. –

2

Âm thanh như một FactoryBean

+0

Không thực sự. Để autowire một 'FactoryBean', bạn cần một thực hiện thực tế cho nó. Từ những gì tôi có thể nói tôi nên sử dụng 'ObjectFactoryCreatingFactoryBean' nhưng nó có vẻ như quá nhiều công việc không có lý do chính đáng. –

+0

Và những gì về phương pháp tra cứu với phạm vi = "nguyên mẫu"? Như thế này: http://stackoverflow.com/a/10358248/1385087 –

+0

Vấn đề là có vẻ như tôi phải thay đổi XML (tôi cố gắng làm hầu hết các bean của mình thông qua các chú thích) cho mỗi cá thể "Nhà cung cấp". Tôi đã nhận thấy rằng Spring hỗ trợ JSR-330, do đó cũng là giao diện của nhà cung cấp, ngoại trừ việc nó không tạo ra những hạt này khi đang chạy, bạn cần phải tự tạo các bean đó - do đó nó hoàn toàn bỏ lỡ điểm. Hơn nữa, không có chú thích phương pháp tra cứu, vì vậy tôi phải thay đổi XML & tạo một lớp mới cho mỗi bean được thừa nhận? –