Должен ли я использовать @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может внедрять любой bean-компонент, а @EJBможет только EJB- компоненты . Вы можете использовать любой из них для внедрения EJB, но я бы предпочел @Injectвезде.

Bozho
источник
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. Надеюсь, это имеет смысл.
Некромант
Я создал два pojo и вводил pojo друг в друга. Работает без проблем в моем конфиге (WildFly 8.2 = CDI 1.2)
Martijn Burger
1
Спасибо @MartijnBurger, я это подтвердлю и добавлю к моему ответу предостережение.
Некромант
Не совсем точно, что вы хотели достичь, но это, вероятно, делает именно то, что вы хотели и без круговой зависимости. tomee.apache.org/examples-trunk/async-postconstruct/README.html . Также асинхронные события CDI могут быть более чистым способом (в зависимости от требований).
января 2015 г.
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 и т. Д., В классе компонента, поскольку у клиента просто не будет доступа к этим метаданным. Кроме того, должны быть указаны некоторые дополнительные метаданные, которые нам не нужны для локального случая (глобальное имя 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.

javierZanetti
источник