Tôi nên sử dụng @EJB hoặc @Inject


148

Tôi đã tìm thấy câu hỏi này: sự khác biệt giữa @Inject và @EJB là gì nhưng tôi không nhận được bất kỳ sự khôn ngoan nào. Tôi chưa từng làm Java EE trước đây và tôi cũng không có kinh nghiệm về việc tiêm phụ thuộc nên tôi không hiểu tôi nên sử dụng cái gì?

Có phải @EJB là một cách tiêm cũ? Việc tiêm EJB được thực hiện khi sử dụng chú thích này trong khi sử dụng @Inject có sử dụng khung CDI mới không? Đó 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?

Câu trả lời:


178

@EJBđược sử dụng để tiêm chỉ EJB và có sẵn trong một thời gian khá lâu. @Injectcó 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 có thể chỉ cần thay đổi @EJBthà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 @EJBcác thuộc tính như beanName, lookuphoặc beanInterface) hơn là để sử dụng, @Injectbạn sẽ cần xác định một @Producertrường hoặc phương thức.

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

Blog của Antonio Goncalves:
CDI Phần I
CDI Phần II
CDI Phần III

Tài liệu của JBoss Weld:
CDI và hệ sinh thái Java EE

StackOverflow:
Tiêm đậu @EJB dựa trên các điều kiện


4
Tại sao làm @EJBviệc cho tiêm tròn (một đậu đơn và một đậu khác cần tham chiếu với nhau)? (có tham khảo câu trả lời của tôi dưới đây - tôi không chắc mình có làm đúng hay không bằng cách chuyển sang @EJB)
necromancer

2
bởi vì bạn không tiêm thực hiện, mà là một proxy can thiệp vào việc thực hiện. bởi vì điều này, bạn có được những lợi thế của "ràng buộc muộn" và các tính năng chứa khác.
anh ấy

33

@Injectcó thể tiêm bất kỳ loại đậu nào, trong khi @EJBchỉ có thể tiêm EJB. Bạn có thể sử dụng hoặc để tiêm EJB, nhưng tôi thích @Injectở mọi nơi.


1
Điều gì chính xác làm cho tiêm khi chúng ta sử dụng @Inject? Container JavaEE? Nó có thể tiêm POJO không?
Koray Tugay

3
với CDI, đó là bộ chứa CDI (được đóng gói trong bộ chứa JavaEE)
Bozho

16

Cập nhật: Câu trả lời này có thể không chính xác hoặc lỗi thời. Xin vui lòng xem ý kiến ​​để biết chi tiết.

Tôi chuyển từ @Injecttới @EJB@EJBcho phép tiêm tròn trong khi @Injectpukes trên đó.

Chi tiết: Tôi cần @PostConstructgọi một @Asynchronousphương thức nhưng nó 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à gọi 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 ban đầu. Để làm điều này, mỗi hạt cần một tham chiếu đến cái khác - do đó thông tư. @Injectthất bại cho nhiệm vụ này trong khi @EJBlàm việc.


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

Tôi đã tạo hai pojo và tiêm các pojo vào nhau. Hoạt động không có vấn đề trong cấu hình của tôi (WildFly 8.2 = CDI 1.2)
Martijn Burger

1
Cảm ơn @MartijnBurger, tôi sẽ xác nhận điều đó và trong khi đó hãy thêm một lưu ý cho câu trả lời của tôi.
Necromancer

Không chắc chắn chính xác những gì bạn muốn đạt được, nhưng điều này có thể làm chính xác những gì bạn muốn và không có sự phụ thuộc vòng tròn. tomee.apache.org/examples-trunk/async-postconstruct/README.html . Ngoài ra các sự kiện CDI không đồng bộ có thể là một cách dễ dàng hơn (tùy thuộc vào yêu cầu).
JanM

12

Đây là một cuộc thảo luận tốt về chủ đề này. Gavin King khuyến nghị @Inject hơn @EJB cho các EJB không từ xa.

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

hoặc là

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

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

  1. Tháng 11 năm 2009, 20:48 Mỹ / New_York | Liên kết vua

Lỗi đó rất lạ, vì các tham chiếu cục bộ EJB phải luôn được tuần tự hóa. Lỗi trong cá thủy tinh, có lẽ?

Về cơ bản, @Inject luôn 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 không nên sử dụng @EJB ngoại trừ việc khai báo các tham chiếu đến các EJB từ xa.

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

  1. Tháng 11 năm 2009, 17:42 Mỹ / New_York | Liên kết vua

    Điều đó có nghĩa là @EJB tốt hơn với các EJB từ xa?

Đối với EJB từ xa, chúng tôi không thể khai báo siêu dữ liệu như vòng loại, @Alternative, v.v., trên lớp bean, vì máy khách đơn giản là sẽ không 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 cục bộ (tên JNDI toàn cầu của bất cứ điều gì). Vì vậy, tất cả những thứ đó cần phải đi đến một nơi khác: cụ thể là khai báo @ sản phẩm.


1
Mặc dù điều này về mặt lý thuyết có thể trả lời câu hỏi, tốt hơn là nê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ả khi liên kết đã chết.
Mifeet


4

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

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

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

xem thêm danh tính đậu phiên phi trạng thái để biết thêm thông tin


0

Việc tiêm đã tồn tại trong Java EE 5 với các chú thích @Resource, @PersistentUnit hoặc @EJB, chẳng hạn. Nhưng nó bị 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, bean hỗ trợ JSF ..). Với CDI, bạn có thể tiêm gần như mọi thứ ở bất cứ đâu nhờ chú thích @Inject.

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.