Чи варто використовувати @EJB або @Inject


148

Я знайшов це запитання: в чому різниця між @Inject та @EJB, але я не став мудрішим. Я раніше не робив Java EE і не маю досвіду введення залежності, тому я не розумію, що мені слід використовувати?

Чи @EJB - це старий спосіб введення? Чи робиться ін'єкція контейнером EJB при використанні цієї анотації під час використання @Inject нову рамку CDI? Це різниця, і чи слід використовувати @Inject замість @EJB, якщо це так?

Відповіді:


178

@EJBВикористовується для введення об'єкта EJB тільки і доступний в протягом досить тривалого часу. @Injectможе вводити будь-який керований боб і є частиною нової специфікації CDI (з Java EE 6).

У простих випадках ви можете просто змінити @EJBдо @Inject. У більш розвинених випадках (наприклад, коли ви сильно залежите від @EJBтаких атрибутів, як beanName, lookupабо beanInterface), ніж для їх використання, @Injectвам потрібно буде визначити @Producerполе чи метод.

Ці ресурси можуть бути корисні для розуміння відмінностей між @EJBі @Producesі як отримати кращі з них:

Блог Антоніо Гонкальвеса:
CDI Частина I
CDI Частина II
CDI Частина III

Документація JBoss Weld:
CDI та екосистема Java EE

StackOverflow:
впорскуйте стручковий @EJB на основі умов


4
чому @EJBпрацює циркулярна ін'єкція (один однотонний та інший квасоля потребують посилання один на одного)? (з посиланням на мою відповідь нижче - я не впевнений, чи правильно роблю, перейшовши на @EJB)
некроман

2
тому що ви не вкладаєте реалізацію, а проксі, який втручається у реалізацію. через це ви отримуєте переваги «пізнього зв’язування» та інших функцій контейнера.
його

33

@Injectможе вводити будь-яку квасолю, в той час як @EJBможе вводити лише EJB. Ви можете використовувати або для введення EJB, але я вважаю за краще @Injectскрізь.


1
Що саме робить ін'єкцію, коли ми використовуємо @Inject? Контейнер JavaEE? Чи може він вводити POJO?
Корай Тугай

3
з CDI - це контейнер CDI (в комплекті з контейнером JavaEE)
Божо

16

Оновлення: ця відповідь може бути неправильною або застарілою. Будь ласка, дивіться коментарі для деталей.

Я перейшов @Injectна, @EJBтому що @EJBдозволяє кругової ін'єкції, тоді як@Inject тягне на неї.

Деталі: Мені потрібно @PostConstructбуло викликати @Asynchronousметод, але він зробив би це синхронно. Єдиний спосіб здійснити асинхронний виклик - це мати оригінальний виклик методом іншого біна і змусити його відкликати метод вихідного бона. Для цього кожен боб потребував посилання на іншого - таким чином, кругового. @Injectне вдалося виконати це завдання, тоді як @EJBпрацював.


@MartijnBurger Я не маю під рукою код, а також середовище Java EE. Просто створіть 2 класи Java та @Injectїх у загальнодоступні поля один одного. Якщо це працює, то моя відповідь неправильна. Якщо це не працює, то поки що моя відповідь правильна. Далі змініть @Injectна @EJB(і, можливо, анотуйте самі класи? Забуваю.) Тоді циклічна взаємна ін'єкція повинна справно працювати. Ось чому я перейшов @Injectна @EJB. Сподіваюся, це має сенс.
некроман

Я створив два пуджо і ввів індустрію. Працює без проблем у моїй конфігурації (WildFly 8.2 = CDI 1.2)
Martijn Burger

1
Дякую @MartijnBurger, я підтверджу це, а тим часом додаю ноту обережності до своєї відповіді.
некроман

Не точно впевнене, чого ви хотіли досягти, але це, ймовірно, робить саме те, що ви хотіли, і без кругової залежності. tomee.apache.org/examples-trunk/async-postconstruct/README.html . Також асинхронні події CDI можуть бути більш чистим шляхом (залежно від вимог).
січня

12

Ось хороша дискусія з цієї теми. Гевін Кінг рекомендує @Inject over @EJB для не віддалених EJB.

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

або

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

Re: Ін'єкції за допомогою @EJB або @Inject?

  1. Листопад 2009, 20:48 Америка / New_York | Посилання Гевін Кінг

Ця помилка дуже дивна, оскільки місцеві посилання EJB завжди повинні бути серійними. Баг у скляній рибі, мабуть?

В основному, @Inject завжди краще, оскільки:

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

Я не рекомендую використовувати @EJB за винятком декларування посилань на віддалені EJB.

і

Re: Ін'єкції за допомогою @EJB або @Inject?

  1. Листопад 2009, 17:42 Америка / New_York | Посилання Гевін Кінг

    Чи означає це @EJB краще з віддаленими EJB?

Для віддаленого EJB ми не можемо оголосити метадані, як кваліфікатори, @Alternative тощо, для класу bean, оскільки клієнт просто не матиме доступу до цих метаданих. Крім того, необхідно вказати деякі додаткові метадані, які нам не потрібні для локального випадку (глобальна назва JNDI). Тому все це потрібно подати кудись інше: а саме декларацію @Produces.


1
Хоча це теоретично може відповісти на питання, бажано було б сюди включити істотні частини відповіді та надати посилання для довідки. Таким чином ця відповідь була б корисною навіть зараз, коли посилання мертва.
Mifeet


4

Можливо, також буде корисним зрозуміти різницю в терміні ідентичності сеансу при використанні @EJB та @Inject. Відповідно до специфікацій, наступний код завжди буде true:

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

Використання @Inject замість @EJB не те саме.

див. також ідентифікацію бобів сеансу без громадянства для отримання додаткової інформації


0

Інжекції вже існували в Java EE 5 за допомогою приміток @Resource, @PersistentUnit або @EJB. Але воно обмежувалося певними ресурсами (джерелом даних, EJB ...) та певними компонентами (сервлети, EJB, резервна квадратика JSF ...). Завдяки CDI ви можете вводити майже будь-що куди завгодно завдяки примітці @Inject.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.