2011-11-15 42 views
125

Tôi đã tìm thấy câu hỏi này: What is the difference between @Inject and @EJB nhưng tôi đã không nhận được bất kỳ khôn ngoan hơn. Tôi đã không thực hiện Java EE trước đây và cũng không có kinh nghiệm với việc tiêm phụ thuộc vì vậy tôi không hiểu những gì tôi nên sử dụng?Tôi có nên sử dụng @EJB hoặc @Inject

Có phải @EJB và cách tiêm cũ không? Là tiêm được thực hiện bởi các container EJB khi sử dụng chú thích này trong khi sử dụng @Inject sử dụng khung CDI mới? Đó có phải là sự khác biệt và tôi nên sử dụng @Inject thay vì @EJB nếu đây là trường hợp không?

Trả lời

155

@EJB được sử dụng để chỉ tiêm EJB và hiện có sẵn trong một thời gian. @Inject có thể tiêm bất kỳ bean được quản lý nào và là một phần của đặc tả CDI mới (kể từ Java EE 6).

Trong trường hợp đơn giản, bạn chỉ cần thay đổi @EJB thành @Inject. Trong các trường hợp nâng cao hơn (ví dụ: khi bạn phụ thuộc nhiều vào các thuộc tính của @EJB như beanName, lookup hoặc beanInterface) so với sử dụng @Inject, bạn sẽ cần xác định trường hoặc phương pháp @Producer.

Những nguồn này có thể hữu ích để hiểu được sự khác nhau giữa @EJB@Produces và làm thế nào để tận dụng tốt nhất của họ:

Antonio Goncalves' blog:
CDI Part I
CDI Part II
CDI Part III

JBoss Weld tài liệu:
CDI and the Java EE ecosystem

StackOverflow:
Inject @EJB bean based on conditions

+3

tại sao '@ EJB' hoạt động để tiêm tròn (một hạt đơn và đậu khác cần tham chiếu với nhau)? (với tham chiếu đến câu trả lời của tôi dưới đây - tôi không chắc chắn nếu tôi đang làm điều đúng bằng cách chuyển sang '@ EJB') – necromancer

28

@Inject có thể tiêm bất kỳ hạt nào, trong khi @EJB chỉ có thể tiêm EJB. Bạn có thể sử dụng một trong hai để tiêm EJB, nhưng tôi thích @Inject ở khắp mọi nơi.

+1

Chính xác điều gì làm cho việc tiêm khi chúng tôi sử dụng @Inject? Vùng chứa JavaEE? Nó có thể tiêm POJO không? –

+3

với CDI đó là thùng chứa CDI (được đóng gói trong thùng chứa JavaEE) – Bozho

11

Đây là cuộc thảo luận tốt về chủ đề. Gavin King đề xuất @Inject trên @EJB cho các EJB không từ xa.

http://www.seamframework.org/107780.lace

hoặc

https://web.archive.org/web/20140812065624/http://www.seamframework.org/107780.lace

Re: Tiêm với @EJB hoặc @Inject?

  1. Nov 2009, 20:48 America/New_York | Liên kết Gavin King

Lỗi này rất lạ, vì tham chiếu cục bộ EJB phải luôn là được nối tiếp. Lỗi trong thủy tinh, có lẽ?

Về cơ bản, @Inject phải lúc nào cũng tốt hơn, vì:

it is more typesafe, 
it supports @Alternatives, and 
it is aware of the scope of the injected object. 

Tôi khuyên bạn nên chống lại việc sử dụng @EJB trừ khai báo tham chiếu đến EJB từ xa.

Re: Tiêm với @EJB hoặc @Inject?

  1. Nov 2009, 17:42 America/New_York | Liên kết Gavin King

    Có nghĩa là @EJB tốt hơn với EJB từ xa không?

Đối với một EJB từ xa, chúng ta không thể tuyên bố siêu dữ liệu như vòng loại, @Alternative, vv, trên lớp bean, kể từ khi khách hàng chỉ đơn giản là không phải là sẽ có quyền truy cập vào siêu dữ liệu đó. Hơn nữa, một số siêu dữ liệu bổ sung phải được chỉ định mà chúng tôi không cần cho trường hợp địa phương (tên JNDI toàn cầu của bất kỳ thứ gì). Vì vậy, tất cả những thứ cần phải đi ở một nơi khác: cụ thể là tuyên bố @Produces.

+1

Trong khi điều này về mặt lý thuyết có thể trả lời câu hỏi, nó sẽ là thích hợp hơn để bao gồm các phần thiết yếu của câu trả lời ở đây, và cung cấp liên kết để tham khảo. Bằng cách đó câu trả lời này sẽ có giá trị ngay cả bây giờ khi liên kết đã chết. – Mifeet

+0

@John Manko, trang ra ... lỗi 404 ... :( –

+1

https: //web.archive.org/web/20140812065624/http: //www.seamframework.org/107780.lace –

11

Cập nhật: Câu trả lời này có thể không đúng hoặc lỗi thời. Vui lòng xem nhận xét để biết chi tiết.

Tôi đã chuyển từ @Inject thành @EJB@EJB cho phép tiêm tròn trong khi @Inject pukes trên đó.

Chi tiết: Tôi cần @PostConstruct để gọi phương thức @Asynchronous nhưng sẽ thực hiện đồng bộ. Cách duy nhất để thực hiện cuộc gọi không đồng bộ là có cuộc gọi ban đầu là phương thức của một bean khác và yêu cầu nó gọi lại phương thức của bean gốc. Để làm điều này, mỗi hạt cần một tham chiếu đến cái kia - do đó hình tròn. @Inject không thành công cho tác vụ này trong khi @EJB hoạt động.

+0

Bạn có thể thêm một ví dụ mã giải thích điều này không? –

+0

@MartijnBurger Tôi không có mã tiện dụng, cũng không phải là một môi trường Java EE tiện dụng. Chỉ cần tạo 2 lớp Java và '@ Tiêm' chúng vào các trường công khai của nhau. Nếu điều đó hoạt động thì câu trả lời của tôi là sai. Nếu điều đó không hiệu quả, thì câu trả lời của tôi là chính xác cho đến giờ. Tiếp theo, thay đổi '@ Inject' thành' @ EJB' (và có thể chú thích các lớp đó? Tôi quên.). Sau đó tiêm tuần hoàn lẫn nhau sẽ hoạt động tốt. Đó là lý do tại sao tôi chuyển từ '@ Inject' sang' @ EJB'. Hy vọng điều này có ý nghĩa. – necromancer

+0

Tôi đã tạo ra hai bài thơ và đưa các pojo vào nhau. Hoạt động mà không có vấn đề trong cấu hình của tôi (WildFly 8.2 = CDI 1.2) –

0

Tiêm đã tồn tại trong Java EE 5 với chú thích @Resource, @PersistentUnit hoặc @EJB chẳng hạn. Nhưng nó được giới hạn ở một số tài nguyên nhất định (nguồn dữ liệu, EJB ...) và vào một số thành phần nhất định (Servlets, EJBs, JSF ủng hộ bean ...). Với CDI, bạn có thể tiêm gần như mọi thứ bất cứ nơi nào nhờ chú thích @Inject.

2

Cũng có thể hữu ích khi hiểu sự khác biệt về thuật ngữ Phiên Bean khi sử dụng @EJB và @Inject. Theo thông số kỹ thuật đoạn mã sau sẽ luôn luôn được true:

@EJB Cart cart1; 
@EJB Cart cart2; 
… if (cart1.equals(cart2)) { // this test must return true ...} 

Sử dụng @Inject thay vì @EJB có không giống nhau.

xem thêm stateless session beans identity để biết thêm thông tin

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