Как инъекция CDI работает в MDB и бинах @Scheduled?

Я работаю над большим приложением Java EE 6, которое развернуто на JBoss 6 Final. Мои текущие задачи включают постоянное использование @Inject вместо @EJB, но я сталкиваюсь с некоторыми проблемами на некоторых типах bean-компонентов, в частности на bean-компонентах @MessageDriven и bean-компонентах с методами @Scheduled.

Случается так, что если мне не повезло с синхронизацией (для @Schedule) или если при запуске есть сообщения в очередях MDBs, создание экземпляров bean-компонентов завершится неудачей, потому что внедренные ресурсы (которые сами являются EJB) еще не связаны,

Поскольку я использую @Inject, я предполагаю, что контейнер EJB считает, что мои бины готовы, так как сам контейнер не заботится о @Inject; это, вероятно, просто предполагает, что, поскольку нет инъекций @EJB, бины готовы к использованию. Внедренные прокси-серверы CDI в этом случае потерпят неудачу, потому что ресурсы для внедрения на самом деле еще не связаны.

Крошечный пример:

@Stateless
@LocalBean
public class MySupportingBean {

    public void doSomething() {
        ...
    }
}

@Singleton
public class MyScheduledBean {

    @Inject
    private MySupportingBean supportingBean;

    @Schedule(second = "*/1", hour = "*", minute = "*", persistent = false)
    public void onTimeout() {
        supportingBean.doSomething();
    }
}

Приведенный выше пример, вероятно, не будет часто терпеть неудачу, потому что есть только два bean-компонента, но проект, над которым я работаю, связывает множество EJB-компонентов, что усилит проблему. Но это может произойти сбой, потому что нет гарантии, что MySupportingBean будет привязан первым, и если onTimeout вызывается до того, как MySupportingBean будет привязан, то создание экземпляра MyScheduledBean завершится неудачно. Если бы вместо этого я использовал @EJB, MyScheduledBean не был бы связан, пока не была удовлетворена зависимость от MySupportingBean.

Обратите внимание, что в примере не произойдет сбой в самом onTimeout, но когда CDI попытается внедрить MySupportingBean.

Я прочитал много постов на разных форумах, где многие люди утверждают, что @Inject всегда лучше. В общем, я согласен, но как они обрабатывают @Schedule или @MessageDriven в сочетании с @Inject? По моему опыту, просто глупо везет, будут ли работать bean-компоненты в этих случаях или нет, и bean-компоненты будут зависать произвольно, в зависимости от того, в каком порядке развернуты EJB, и когда вызываются @Schedule или onMessage.

1 ответ

Это может помочь явно определить зависимости, используя собственную аннотацию JBoss @Depends или используя файл jboss.xml.

Посмотрите на этот вопрос несколько схожий вопрос: как заказать развертывание конфигурации EJB и очереди JMS в JBoss 5?

Другие вопросы по тегам