Внедрение зависимостей через конструктор не работает для EJB-компонента - PullRequest
0 голосов
/ 19 ноября 2018

Мое приложение разворачивается в IBM WebSphere. У меня есть простой сервис, и я хотел бы знать, как в этом случае работает внедрение зависимостей.

// stateless EJB
@Stateless
public class UserService {

    private UserDAO userDAO;

    // btw, UserDAO is stateless EJB as well
    @Inject
    public UserService(UserDAO userDAO) {
        this.userDAO = userDAO;    
    }

    // biz methods ...
}

Сбой из-за следующей ошибки:

[ОШИБКА] CWWKZ0002E: Возникла исключительная ситуация при запуске приложение my-app. Сообщение об исключении было: com.ibm.ws.container.service.state.StateChangeException: com.ibm.ws.cdi.CDIException: com.ibm.wsspi.injectionengine.InjectionException: com.ibm.ejs.container.EJBConfigurationException: класс EJB com.demo.app.UserService должен иметь открытый конструктор, который не принимает параметров

Я помню, что в спецификации EJB было что-то, что говорит: the class must have a public constructor that takes no parameters, и для меня имеет смысл, что экземпляр компонента сначала создается контейнером, а затем выполняется внедрение зависимостей .

С другой стороны, я нашел это в WELD документах:

Во-первых, контейнер вызывает конструктор бина (по умолчанию конструктор или аннотированный @Inject), чтобы получить экземпляр боб.

И я немного запутался, почему мой EJB не может быть создан.

Как создается экземпляр EJB и внедряются зависимости, когда у нас есть точка внедрения конструктора?

Есть идеи? :)

Ответы [ 3 ]

0 голосов
/ 20 ноября 2018

создание сессионных EJB-компонентов выполняется контейнером EJB, но он может использовать CDI для обеспечения инъекции ресурсов EE, но разрешение EJB делегируется контейнеру

https://docs.jboss.org/weld/reference/2.1.0.Final/en-US/html/ri-spi.html говорит:

В качестве альтернативы, интегратор может выбрать использование CDI для обеспечения внедрения ресурсов EE.В этом случае должна использоваться среда EE_INJECT, и интегратор должен реализовать Раздел A.1.4, «Службы EJB», Раздел A.1.7, «Службы ресурсов» и Раздел A.1.5, «Службы JPA».....
Сварка регистрирует точки внедрения ресурсов с помощью предварительных реализаций EjbInjectionServices, JpaInjectionServices, ResourceInjectionServices и JaxwsInjectionServices (при начальной загрузке).Это позволяет выполнять проверку точек внедрения ресурсов во время загрузки, а не во время выполнения

, если вы заинтересованы в интеграции CDI и EJB.Вы можете взглянуть на код модуля сварки-EJB и интеграции сварки (код Glassfish)

0 голосов
/ 20 ноября 2018

Итак, вы не соответствуете требованиям для инициализации EJB-компонентов.

Спецификация CDI имеет некоторые ограничения на конструкторы - без аргументов или с @Inject.Но есть также эта глава , которая указывает, что в EE набор правил расширяется тем, что требуется сессионным компонентам EJB.

И теперь мы переходим к спецификации EJB, которая требует-арг конструктор на боб.Это должно быть в главе Enterprise Bean Class, где говорится:

Класс должен определить открытый конструктор, который не принимает аргументов.

Теперь, наконец, перейдем кдолжно ли это работать - например, можете ли вы иметь EJB-компонент, использующий инъекцию конструктора CDI?Что ж, давайте посмотрим на CDI TCK, набор тестов, которые должны пройти все реализации и контейнеры, чтобы иметь возможность утверждать, что они реализуют CDI.Там мы можем увидеть этот бин и этот тест с его использованием - так что да, это может сработать, но вам нужно иметь оба конструктора.

0 голосов
/ 19 ноября 2018

EJB регистрируются как компоненты CDI.Но сначала они должны соответствовать требованиям спецификации EJB.

Полагаю, это работает просто путем предоставления конструктора no-args.

...