Исключить / удалить службы из-за отсутствия зависимости в JBoss

#java #jboss #dependency-injection

#java #jboss #внедрение зависимости

Вопрос:

В настоящее время у нас есть проект, который состоит из нескольких приложений, а также базовой библиотеки. Оба приложения, а также базовая библиотека содержат EJB без состояния, и каждое приложение может вводить EJB, который наследуется от базовой библиотеки EJBand, таким образом, реализует один и тот же интерфейс.

Короткий пример:

В базовой библиотеке мы имеем:

 @Stateless
@Local( IUserService.class ) 
public UserServiceBean implements IUserService {
  public void login(String user, String password) {...}
}
  

В приложении нам нужно переопределить login(...) и, таким образом, мы имеем:

 @Stateless
@Local( { ISpecificUserService.class, IUserService.class } ) 
public SpecificUserServiceBean extends UserServiceBean implements ISpecificUserService {
  public void login(String user, String password) { ... } //override
}
  

Если бы у меня теперь был другой EJB в приложении, на который должна быть ссылка, SpecificUserServiceBean я бы сделал @EJB ISpecificUserService userService; .

Однако, если в базовой библиотеке есть EJB, он будет содержать @EJB IUserService userService; и вот в чем проблема:

Нам нужно, чтобы конкретная служба в приложении была введена в базовую библиотеку EJB. Однако для одного и того же локального интерфейса зарегистрированы два EJB, что означает, что контейнер может возвращать базовый EJB или конкретный EJB.

Вы могли бы сказать «Не добавляйте базовую библиотеку jar в качестве модуля в application.xml » но сейчас это невозможно, поскольку он содержит другие EJB, которые необходимо развернуть. Мы могли бы переместить EJB для переопределения в другой jar, но поскольку почти каждый EJB может быть переопределен, в зависимости от приложения, в итоге мы получили бы jar для каждого EJB.

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

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

У вас есть какие-либо идеи о том, что мы могли бы сделать?

Заранее спасибо.

Кстати, мы работаем над JBoss 4.2.3 с EJB 3.0.

Ответ №1:

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

Итак, решение состоит в том, чтобы удалить @Stateless @Local( IUserService.class ) из UserServiceBean вашей базовой библиотеки; базовая библиотека просто предоставляет реализации по умолчанию для компонентов, но она не должна их подключать.

В ваших приложениях вам нужен этот код:

 @Stateless
@Local( IUserService.class ) 
public AppUserServiceBean extends UserServiceBean {}
  

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

Комментарии:

1. Это тоже было бы решением. Однако это потребовало бы от нас дублирования всех наших EJB в каждом приложении, даже если они используются только для подключения.

2. Я только что нашел JBoss 5 jboss-scanning.xml что могло бы стать решением, если бы мы могли переключиться на JBoss 5. С помощью этого файла мы могли бы исключить базовые службы из сканирования, и они, таким образом, не были бы развернуты. Однако мне все равно придется это протестировать.

3. Spring решает ту же проблему с многоуровневостью: вы можете загружать контексты в дереве, а родительские слои скрывают нижние слои. Это прерывается, если на нижних уровнях уже созданы компоненты (существующие компоненты не получают новые, перезаписанные компоненты, введенные). Но если вы загружаете все слои при запуске (что вы обычно делаете), это работает довольно хорошо.

4. @Aaron Это звучит как хорошее решение, спасибо. К сожалению, я сомневаюсь, что смогу заставить своего босса разрешить фундаментальную реструктуризацию с EJB 3 на Spring. Однако, если нет способа сделать это с помощью EJB 3 , я мог бы убедить его.

5. @Thomas: Я упомянул Spring в качестве примера; Я не предлагаю вам переключаться на него — если только вы не можете решить проблему. В этом случае следует учитывать затраты на обслуживание, а не на преобразование части вашего приложения в Spring. Spring — это неинвазивная технология. Вам не нужно отказываться от EJB и вам не обязательно использовать его везде.