2012-06-21 31 views
7

Các JSR-299 đặc điểm kỹ thuật quốc gia trong §3.1:Generics Restricted với CDI

Nếu lớp bean được quản lý là một loại chung chung, nó phải có phạm vi @Dependent. Nếu một bean được quản lý với một lớp bean được tham số khai báo bất kỳ phạm vi nào khác ngoài @Dependent, vùng chứa sẽ tự động phát hiện vấn đề và xử lý nó như một lỗi định nghĩa.

có hiệu quả có nghĩa là bạn không thể làm điều này:

@Named 
@SessionScoped or @RequestScoped or similar 
public class MyProducer<T> {...} 

những lý do kỹ thuật đối với quyết định này là gì?

Nó có được khắc phục trong phiên bản CDI sắp tới không?

Có phương pháp hay nhất để giải quyết/giải quyết vấn đề này không?

Cảm ơn bạn

EDIT - một workaround tôi thường có thể sử dụng là tiêm một generic POJO-đậu vào một bean với phạm vi cần thiết. Thông thường, nhưng không phải lúc nào.

+0

Câu hỏi hay, tiện thể.Tôi không biết về hạn chế này, và nó thực sự khiến bạn suy nghĩ. –

Trả lời

13

Dưới đây là một chung, không phụ thuộc vào lớp bean:

@ApplicationScoped 
public class FavouriteChooser<T> { 
    public T getFavourite() { 
     // ... 
    } 
} 

Có bao nhiêu trường hợp của đậu này sẽ có trong ứng dụng?

Dưới đây là một vị trí tiêm:

@Inject 
private FavouriteChooser<String> favouriteWord; 

Và đây là một:

@Inject 
private FavouriteChooser<Integer> favouriteNumber; 

Bạn có muốn thay đổi câu trả lời của bạn? : D

Ooh, và đây là một:

@Inject 
private FavouriteChooser<CharSequence> favouriteLetters; 

EDIT. Nếu bạn muốn một giải pháp, tôi sẽ đề nghị làm cho lớp trừu tượng chung của bạn, và thêm các lớp con cụ thể liên kết kiểu. Vì vậy:

public abstract class MyProducer<T> {...} 

@Named 
@SessionScoped 
public class MyStringProducer extends MyProducer<String> {} 

@Named 
@SessionScoped 
public class MyIntegerProducer extends MyProducer<Integer> {} 

Đó là bản mẫu, nhưng chỉ có ba dòng cho mỗi loại. Lưu ý rằng sẽ cung cấp cho bạn một phiên bản mỗi phiên cho mỗi loại, mà bạn có thể không muốn.

+0

Đẹp - miễn là bạn không chế biến đậu, nó có thể được tiêm? Nếu phạm vi được bảo tồn (là nó? - là mỗi FavouriteChooser tiêm-ứng dụng-scoped?) Hơn hạn chế duy nhất sẽ là tôi không thể truy cập chúng với EL explressions? Và không phải là mâu thuẫn với spec? Nó được coi là một bean được quản lý sau khi tất cả. – kostja

+3

Không, quan điểm của tôi là mã này không thể hoạt động! Tôi đã tuyên bố 'FavouriteChooser' ứng dụng-scoped, có nghĩa là chỉ có thể có một ví dụ. Nhưng có hai vị trí tiêm cho nó mà * không thể được thỏa mãn bởi cùng một đối tượng *. Và điều đó, tôi nghĩ, là lý do tại sao bạn không thể tiêm các thể hiện của các lớp chung trong bất kỳ phạm vi nào khác ngoài phụ thuộc. –

+0

Xin lỗi vì không rõ ràng hơn về những gì tôi đang cố gắng nói khi tôi viết câu trả lời này. Tôi chỉ vội vã tắt mà không có thời gian để giải thích đúng: /. –

2

Tất cả các hạt cà phê không phụ thuộc phải được ủy quyền - AFAIK không thể thực hiện được với các loại chung.

UPDATE:

Tôi rất muốn có thể giải thích rằng chi tiết hơn, nhưng tôi không ;-) Weld sử dụng javassist, và họ nói rằng proxying generic types is possible in principle - mặc dù không được hỗ trợ trực tiếp bởi các API mục cấp đầu . Nhưng chúng ta đang nói về đặc điểm kỹ thuật, không phải việc thực hiện Weld ...

Có thể ai đó khác có thể lấp đầy khoảng trống?

+0

Cảm ơn, jan. Nó sẽ làm sáng tỏ vấn đề - nó sẽ là tuyệt vời nếu bạn cũng có thể giải thích tại sao các loại generic không thể được proxied (tôi đoán nó có sth để làm với hiệu trưởng java nemesis - loại erasure nhưng cant đặt ngón tay của tôi trên nó). – kostja