В случае с удаленными EJB-компонентами, как вы только что видели, вам может потребоваться JNDI-строка для их поиска. Аннотация @Inject не может обладать строковым параметром, так что при этом вам придется создать удаленный EJB-компонент, чтобы вы смогли внедрить его:
// Код для создания удаленного EJB-компонента
@Produces @EJB(lookup = "java: global/classes/ItemEJB") ItemRemote
··itemEJBRemote;
// Клиентский код с внедрением созданного удаленного EJB-компонента
@Inject ItemRemote itemEJBRemote;
В зависимости от клиентской среды у вас может отсутствовать возможность использовать внедрение (если компонент не управляется контейнером). В этом случае попробуйте обратиться к JNDI для поиска сессионных EJB-компонентов с помощью их переносимых JNDI-имен.
Вызов с использованием JNDI
Поиск сессионных EJB-компонентов также можно осуществлять с использованием JNDI, который главным образом применяется для удаленного доступа, когда клиент не управляется контейнером и не может применять внедрение зависимостей. Однако JNDI также может задействоваться локальными клиентами, хотя внедрение зависимостей приводит к тому, что код становится более простым. Внедрение осуществляется во время развертывания. Если есть вероятность того, что данные не будут использоваться, EJB-компонент может избежать затрат, связанных с внедрением ресурсов, выполнив JNDI-поиск. JNDI является альтернативой внедрению. При использовании JNDI код выталкивает данные из стека, только если они необходимы, вместо того чтобы принимать подвергнутые проталкиванию в стек данные, которые могут вообще не потребоваться.
JNDI — это API-интерфейс для доступа к службам каталогов, позволяющий клиентам осуществлять привязку и поиск объектов по имени. JNDI определяется в Java SE и не зависит от базовой реализации, то есть вы можете выполнять поиск объектов в каталоге Lightweight Directory Access Protocol (LDAP) или системе доменных имен (DNS), используя стандартный API-интерфейс.
В качестве альтернативы предшествующему коду можно использовать InitialContext, связанный с JNDI, и осуществлять поиск развернутого EJB-компонента с помощью его переносимого JNDI-имени, которое я определил ранее в подразделе «Переносимое JNDI-имя» раздела «Написание корпоративных EJB-компонентов» данной главы. Клиентский код будет выглядеть следующим образом:
Context ctx = new InitialContext();
ItemRemote itemEJB = (ItemRemote)
··ctx.lookup("java: global/cdbookstore/ItemEJB!org.agoncal.book.javaee7.ItemRemote");
Резюме
Спецификация EJB эволюционировала годами, начиная с версии EJB 2.
Сессионные EJB-компоненты являются компонентами, управляемыми контейнером, которые используются для разработки бизнес-уровней. Есть три типа сессионных EJB-компонентов: без сохранения состояния, с сохранением состояния и одиночные. Первые — легко масштабируемы, поскольку не поддерживают никакого состояния, располагаются в пуле и решают задачи, с которыми можно справиться одним вызовом метода. Между EJB-компонентами с сохранением состояния и клиентом имеет место корреляция «один к одному», кроме того, они могут быть временно удалены из памяти с использованием пассивизации и активизации. Одиночные EJB-компоненты обладают уникальным экземпляром, который совместно применяется несколькими клиентами и может инициализироваться во время запуска, объединяться в цепочку с другими экземплярами и настраиваться при осуществлении клиентами конкурентного доступа.
Несмотря на эти различия, сессионные EJB-компоненты совместно используют общую модель программирования. Они могут обладать локальным представлением, удаленным представлением или представлением без интерфейса, задействовать аннотации или быть развернутыми с применением дескриптора развертывания. Сессионные EJB-компоненты могут применять внедрение зависимостей для получения ссылок на несколько ресурсов (источники данных JDBC, контекст постоянства, записи окружения и т. д.), а также на их контекст среды выполнения (объект SessionContext). С выходом EJB 3.1 у вас появилась возможность вызывать методы асинхронно, выполнять поиск EJB-компонентов с использованием переносимых JNDI-имен и задействовать встраиваемый EJB-контейнер в среде Java SE. Версия EJB 3.2 идет по пути своей предшественницы, привнося небольшие улучшения.