··public void addToCache(Long id, Object object) {
····if (!cache.containsKey(id))
······cache.put(id, object);
··}
··public void removeFromCache(Long id) {
····if (cache.containsKey(id))
······cache.remove(id);
··}
··@Lock(LockType.READ)
··public Object getFromCache(Long id) {
····if (cache.containsKey(id))
······return cache.get(id);
····else
······return null;
··}
}
Я уже говорил о внедрении зависимостей ранее, и вы столкнетесь с этим механизмом несколько раз в последующих главах. Это простой, но все же мощный механизм, используемый Java EE 7 для внедрения ссылок на ресурсы в атрибуты. Вместо того чтобы приложению искать ресурсы с использованием JNDI, контейнер сам внедряет их. Внедрение осуществляется во время развертывания. Если есть вероятность того, что данные не будут использоваться, EJB-компонент может избежать затрат, связанных с внедрением ресурсов, выполнив JNDI-поиск. JNDI является альтернативой внедрению. При использовании JNDI код выталкивает данные из стека, только если они необходимы, вместо того чтобы принимать подвергнутые проталкиванию в стек данные, которые могут вообще не потребоваться.
Контейнеры могут внедрять ресурсы различных типов в сессионные EJB-компоненты с помощью разных аннотаций (или дескрипторов развертывания):
• @EJB — внедряет ссылку на локальное представление, удаленное представление и представление без интерфейса EJB-компонента в аннотированную переменную;
• @PersistenceContext и @PersistenceUnit — выражают зависимость от EntityManager и EntityManagerFactory соответственно (см. подраздел «Получение менеджера сущностей» раздела «Менеджер сущностей» главы 6);
• @WebServiceRef — внедряет ссылку на веб-службу;
• @Resource — внедряет ряд ресурсов, например источники данных JDBC, SessionContext, пользовательские транзакции, фабрики подключений и пункты назначения JMS, записи окружения, TimerService и т. д.;
• @Inject — внедряет почти все с использованием @Inject и @Produces, как было объяснено в главе 2.
В листинге 7.14 приведен фрагмент кода сессионного EJB-компонента без сохранения состояния. В нем для внедрения различных ресурсов в атрибуты используются разные аннотации. Следует отметить, что этими аннотациями можно снабдить переменные экземпляра, а также методы-сеттеры.
@Stateless
public class ItemEJB {
··@PersistenceContext(unitName = "chapter07PU")
··private EntityManager em;
··@EJB
··private CustomerEJB customerEJB;
··@Inject
··private NumberGenerator generator;
··@WebServiceRef
··private ArtistWebService artistWebService;
··private SessionContext ctx;
··@Resource
··public void setCtx(SessionContext ctx) {
····this.ctx = ctx;
··}
··//…
}
Сессионные EJB-компоненты являются бизнес-компонентами, располагающимися в контейнере. Обычно они не обращаются к контейнеру и не используют контейнерные службы напрямую (управление транзакциями, безопасность, внедрение зависимостей и т. д.). Предусматривается, что контейнер будет прозрачно взаимодействовать с этими службами от имени EJB-компонента (это называется