Шаблон фабрики avaStatic с EJB3/JBoss

Я довольно новичок в EJB и полномасштабных серверах приложений, таких как JBoss, большую часть своей карьеры писал и работал с автономными Java-приложениями специального назначения с ограниченным использованием Java EE. Мне интересно, как лучше всего адаптировать широко используемый шаблон проектирования к EJB3 и JBoss: шаблон статической фабрики. На самом деле это пункт № 1 в книге Джошуа Блоха «Эффективная Java» (2-е издание).

В настоящее время я работаю со следующим заводом:

public class CredentialsProcessorFactory {
    private static final Log log = LogFactory.getLog(CredentialsProcessorFactory.class);
    private static Map<CredentialsType, CredentialsProcessor> PROCESSORS = 
        new HashMap<CredentialsType, CredentialsProcessor>();

    static {
        PROCESSORS.put(CredentialsType.CSV, new CSVCredentialsProcessor());
    }

    private CredentialsProcessorFactory() {}

    public static CredentialsProcessor getProcessor(CredentialsType type) {
       CredentialsProcessor p = PROCESSORS.get(type);
       if(p == null)
           throw new IllegalArgumentException("No CredentialsProcessor registered for type " + type.toString());
       return p;
}

Однако в классах реализации CredentialsProcessor мне требуются внедренные ресурсы, такие как PersistenceContext, поэтому я сделал интерфейс CredentialsProcessor интерфейсом @Local, а каждый из имплементов помечен @Stateless. Теперь я могу найти их в JNDI и использовать внедренные ресурсы.

Но теперь у меня есть дисконнект, потому что я больше не использую фабрику. Моей первой мыслью было изменить метод getProcessor(CredentialsType), чтобы выполнить поиск JNDI и вернуть требуемый экземпляр SLSB, но затем мне нужно настроить и передать правильное квалифицированное имя JNDI. Прежде чем я пойду по этому пути, я хотел провести больше исследований общепринятых практик.

Как этот шаблон проектирования обрабатывается в EJB3/Java EE?


person purecharger    schedule 29.03.2010    source источник


Ответы (2)


Когда вы начинаете играть с фабриками и «настоящим» кодом Java POJO, вам в основном нужно полагаться на JNDI.

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

Когда вы говорите об общем Java-коде, который хочет ссылаться на EJB, им нужно самим искать ресурсы через JNDI.

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

Это просто общее общее правило.

Теперь, для вашего конкретного случая, рассмотрим это.

У вас есть:

static {
    PROCESSORS.put(CredentialsType.CSV, new CSVCredentialsProcessor());
}

Это ничем не отличается от:

static {
    PROCESSORS.put(CredentialsType.CSV, "java:comp/env/ejb/CSVCredentialProcessorSessionBean");
}

Затем в вашем коде getProcessor():

Context c = new InitialContext();
return (CredentialsProcessor) c.lookup(PROCESSORS.get(type));

Смотрите, в основном код идентичен, и ваш заводской интерфейс такой же для клиентов.

Вам нужно «жестко закодировать» ключ поиска JNDI, но теперь вы все равно «жестко кодируете» имена классов, так чем же это отличается?

Существуют некоторые потенциальные проблемы с переносимостью между контейнерами, поскольку всем нравится использовать разные идентификаторы JNDI для имен компонентов. Большую часть этого можно настроить при развертывании, но если нет, то вы можете вытащить эти ключи в файл конфигурации или что-то еще.

В Java EE 6 гарантированно переносимые имена. Если вы не переносите контейнеры сегодня, то вообще не беспокойтесь об этом.

Так что, по сути, это вовсе не разрыв связи.

person Will Hartung    schedule 30.03.2010

С EJB3 обычно не нужно выполнять поиск JNDI. EJB3 поддерживает внедрение зависимостей для EJB и некоторых других типов ресурсов. Если ваш атрибут bean-компонента помечен @EJB, зависимость будет автоматически внедрена контейнером.

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

person Ken Liu    schedule 29.03.2010
comment
Я читал это в спецификации EJB. Как бы вы поступили с фабричным классом, который у меня есть выше? Во-первых, фабрика должна быть EJB, чтобы аннотации перехватывались, верно? Тогда как мне сделать выбор различных реализаций на основе перечисления или строки, как указано выше? - person purecharger; 30.03.2010