it-swarm.com.ru

Что делает аннотация @EJBs?

Я примерно знаю, что делает эта конструкция: она создает EJB SomeType и внедряет объект в другой EJB.

 @EJB(name="name1")
 SomeType someVariable

Теперь у меня есть класс, который начинается так: (Я даю все аннотации на уровне класса, хотя я думаю, что только @EJBs уместен)

@Remote(SomeClass.class)
@Stateless(name="someName")
@EJBs({@EJB(name="name1",beanInterface=Type1.class),
       @EJB(name="name2",beanInterface=Type2.class)})
@TransactionAttribute(TransactionAttributeType.REQUIRED)
@TransactionManagement(TransactionManagementType.CONTAINER)
public class X extends Y{ 
  //code

Что здесь делают @EJB? Они, вероятно, получают или создают объекты "name1" ... из JNDI, но куда они помещают результат? Я не вижу вызова .lookup поблизости, но кодовая база огромна, поэтому я не очень уверен в этом.

Дополнительный вопрос: я предполагаю, что две аннотации @Transaction просто повторяют значения по умолчанию?

UPDATE: Несколько человек заявили, что @EJBs является проприетарным расширением. Это не. Это основная часть Java EE5. Смотрите JavaDoc для деталей. . Это просто контейнер для отдельных аннотаций @EJB.

Я полагаю, что каждый, кто требует эти аннотации EJB, выполняет поиск. Я просто хочу знать, что происходит с результатом этого поиска.

35
hyperman

Аннотация @EJB@Resource, @WebServiceRef и т.д.) Служит двум целям:

  1. Он объявляет ссылку в пространстве имен компонента. Например, @EJB(name="myEJB") создает ссылку Java:comp/env/myEJB. Если вы аннотируете поле и не указываете имя, оно создает ссылку Java:comp/env/com.example.MyClass/myField.
  2. Если аннотация объявляется для метода поля или метода установки, тогда контейнер выполняет внедрение при создании компонента.

Способ разрешения ссылки зависит от того, разрешается ли ссылка для функции lookup("Java:comp/env/myEJB") или из-за внедрения:

  1. Если используется EE 6+, для атрибута lookup требуется поиск JNDI для разрешения цели.
  2. Некоторые серверы приложений поддерживают mappedName, который указывается в зависимости от поставщика. Это обычно реализуется путем выполнения поиска.
  3. Серверы приложений поддерживают привязки во время развертывания. Это обычно реализуется путем выполнения поиска.
  4. Если никакой другой информации о связывании не предоставлено, и интерфейс компонента (beanInterface или тип поля) реализуется только одним EJB-компонентом в приложении, тогда спецификация EJB требует, чтобы он возвращался к этому.
  5. Если никакая другая информация привязки не предоставлена ​​и # 4 не может работать, некоторые серверы приложений будут пытаться выполнить поиск в пространстве имен сервера на основе имени ссылки (например, Java:comp/env/myEJB может вызвать поиск myEJB в пространстве имен сервера).
36
Brett Kail

Ответ Мильена Микича дал мне представление о возможном ответе. Если кто-то, кто знает о JNDI, прочитает это, пожалуйста, скажите мне, если это нормально, как я в основном предполагаю здесь.

По сути, есть два способа заглянуть в дерево JNDI: либо через глобальный путь (/ some/proprietary/path/my/bean), либо через среду вашей программы (Java: comp/env/my/bean). Идея состоит в том, что вы создаете ссылки из глобального пути к вашей локальной среде, а затем ищите компоненты оттуда.

Поэтому @Ejb (name = "Java: comp/env/my/bean", mappedName = "/ some/proprietary/path/my/bean") создаст эту ссылку из кода Java (без файла дескриптора xml).

Это означает, что @Ejb (name = "Java: comp/env/my/bean") само по себе является запретом: он копирует ссылку на себя. Побочным эффектом может быть тот факт, что ваш сервер приложений теперь знает во время компиляции, что эта ссылка необходима, но это все.

2
hyperman

Согласно этой link , в основном эта аннотация позволяет EJB искать внешние EJB относительно своего контекста. Обычно есть более элегантные способы сделать это.

1
Miljen Mikic

Что касается бонусного вопроса: Да, две аннотации относительно транзакций повторяют значения по умолчанию: TransactionManagementType по умолчанию имеет значение CONTAINER (против BEAN), а - default - TransactionAttributeType REQUIRED просто указывает, что если компонент вызывается в контексте транзакции, транзакция продолжается, в противном случае будет инициирована новая транзакция (в отличие от, например, REQUIRES_NEW, которая всегда будет создавать новую передачу). Это на самом деле в деталях не так тривиально, как кажется. спецификация EJB 3.1: 

«13.3.7 Спецификация атрибутов транзакции для методов бина

Поставщик компонентов корпоративного компонента с разграничением управляемых контейнером транзакций может указывать Атрибуты транзакции для методов корпоративного компонента. По умолчанию значением атрибута транзакции Для метода компонента с разграничением транзакций, управляемым контейнером, является атрибут REQUIRED Транзакции, и в этом случае нет необходимости явно указывать атрибут транзакции. [. ..]»

1
William Adams