Лучший способ взаимодействия с EJB в Java EE - PullRequest
3 голосов
/ 10 декабря 2011

У меня есть проект Java EE 6 среднего размера, в котором используется несколько EJB, в том числе один, единственной целью которого является управление вызовами базы данных через JPA.Мой вопрос заключается в том, каков наилучший способ добавить новый класс, который выполняет некоторую случайную функцию, а затем вызывает доступ к базе данных EJB для сохранения данных из этого класса.

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

Мне сказали, что если вы хотите добавить новый логический класс в проект, то это должен быть либо EJB, либоВы можете удаленно интегрировать его, используя JNDI для доступа к элементам EJB и создания своего рода клиентского интерфейса.Прямо сейчас мой новый класс - просто POJO, но он не может получить доступ к функциональности EJB.

Что мне делать в целом?

РЕДАКТИРОВАТЬ: Обратите внимание, мой вопрос НЕ касается доступа к базе данных.Это просто пример, который я использую.Мое предположение более широкое.Я хочу знать, как получить доступ к методам EJB из других классов, которые я создаю.Из одного EJB в другой вы можете просто внедрить другой EJB, поскольку оба они управляются контейнерами.Но, скажем, я создаю другой класс в том же пакете, что и EJB-компоненты. Как можно? Как я могу получить доступ к этим методам?Это возможно?Каковы лучшие практики здесь.

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

1 Ответ

8 голосов
/ 10 декабря 2011

EJB обычно используются для реализации сервисов любого типа.Они очень хорошо интегрируются с JPA, поэтому их часто используют для доступа к БД, но это не единственное их использование.

Для EJB обычно не подходит для моделирования данных.Т.е. они должны быть глаголами в вашем приложении, а не существительными.Таким образом, следующее: неправильно :

@Stateless
@Entity
public class CreditCard { // silly, don't do this!

     @Id
     Long id; + getters/setters
     Data expiration date; + getters/setters
}

Лучше следующее: это сервис, который при запуске приложения извлекает данные о котировках откуда-то:

@Singleton
@Startup
public class QuoteFetcher {

     private List<Quote> quotes; // + getter

     @PostConstruct
     public fetchQuote()
          quotes = SomeUrlBuilder.someUrl().getQuotes();
     }
 }

Ниже приведен обязательный пример DAO:

@Stateless
public class JPAInvoiceDAO implements InvoiceDAO {

     @PersistenceContext
     private EntityManager entityManager;

     public Invoice getById(Long invoiceId) {
           return entityManager.find(invoiceId, Invoice.class);
     }

     // More DAO methods
}

Ниже показано, как используется декларативная безопасность и как компонент ищет что-то, что было внешне отображено в его частный контекст (ENC):

@Stateless
public class TokenFetcher

    @Resource
    private SessionContext sessionContext;

    @RolesAllowed("SYSTEM")
    public Token getToken() {
        return (Token) sessionContext.lookup("token");
    }
}

Вторая часть вопроса, похоже, заключается в том, как использовать эти bean-компоненты в вашем коде.Существует четыре основных метода:

  1. Инъекция в управляемые bean-компоненты
  2. Начальная загрузка через JNDI
  3. Автоматически вызывается при запуске
  4. Автоматически через таймер

Инжекция - это самый простой способ, но только управляемые bean-компоненты являются кандидатами на внедрение (в основном это означает, что среда Java EE создает bean-компонент, и вы не используете new() для его создания).

Например, инъекция:

@ManagedBean
public class InvoiceBacking {

     private Long invoiceId; // + getter/setter
     private Invoice invoice; // + getter

     @EJB
     private InvoiceDAO invoiceDAO;

     @PostConstruct
     public void init() {
          invoice = invoiceDAO.getById(invoiceId);
     }
 }

(также см. Связь в JSF 2.0 # Обработка параметров запроса GET )

Начальная загрузка через JNDI:

 public class SomeQuartzJob implements Job {

     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
          InvoiceDAO invoiceDAO = (InvoiceDAO) new InitialContext().lookup("java:global/myApp/myEJB/InvoiceDAO");
          List<Invoice> openInvoices = invoiceDAO.getAllByOpenStatus();
          // verbose exception handling and closing JNDI context omitted for brevity
     }
  }

Бин @Singleton, показанный ранее, был примером того, как инфраструктура Java EE сама вызывает ваш код при запуске.Для автоматического таймера вы должны использовать аннотацию @Schedule для метода бина.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...