Создавать экземпляры компонентов CDI динамически или внедрять в компоненты, отличные от cdi

Я новичок в CDI и надеюсь, что кто-нибудь может мне помочь.

Что ж, позвольте мне объяснить проблему:
Я реализовал главный компонент, который вызывается JSF EL. Этот bean-компонент обрабатывает список объектов. Представьте себе что-то вроде List<Car>. Эти автомобильные объекты создаются в методе @PostMethod главного компонента.
Кроме того, у меня есть несколько классов обслуживания, например CarServices, который предоставляет что-то вроде public static List<Car> getCarsOfBrand(Session session, Brand brand). Внутри классов обслуживания сеанс Hibernate используется для выполнения запроса и возврата заслуженного списка.
Итак, ну ... Я хотел избавиться от передачи объекта сеанса. Итак, мой план состоял в том, чтобы ввести его. Я создал bean-компонент SessionScoped "PersistenceUnit" (может быть, это имя уже выделено заранее, извините за это ...) с помощью метода public Session getCurrentSession(). Я просто хочу внедрить этот bean-компонент во все мои классы обслуживания, чтобы просто вызвать что-то вроде getCarsOfBrand(Brand brand). Проблема в том, что я не могу внедрить bean-компоненты CDI в не-beans. (Автомобиль в настоящее время просто POJO). Я попытался справиться с этим, объявив автомобиль в компоненте CDI, добавив @SessionScoped. Но следующая проблема заключалась в том, что экземпляры объектов Car были созданы мной, а не контейнером. Я пробовал что-то вроде

@Produces
public Car createCar() {
     return new Car();
}

Но и это не увенчалось успехом: я думал, что этот аннотированный метод возвращает прокси-сервер автомобиля. Но ничего не произошло. Введенное поле внутри автомобиля по-прежнему было пустым, и его метод @PostConstruct также никогда не вызывался.

Так ты можешь мне помочь? Каков правильный подход для внедрения текущего контекста (сеанса) в мои классы обслуживания?

Спасибо! :-)


person Roman B    schedule 26.10.2015    source источник


Ответы (1)


Итак, я нашел решение самостоятельно! :-)

Я аннотирую классы обслуживания как @ApplicationScoped и добавляю все, что мне нужно. Автомобильный класс использует эту услугу, но сам не является компонентом. Для этого я использую DeltaSpike для инъекции, когда устанавливаю объект:

public Car() {
  BeanProvider.injectFields(this);
}

Надеюсь, я смогу помочь кому-то в будущем! :-)

person Roman B    schedule 26.10.2015
comment
Вы пропускаете ссылку this в конструкторе. Не надо. Может случиться много неуловимых ужасов. А размещение экземпляров bean-компонентов CDI как атрибутов bean-компонентов, не управляемых CDI, вызовет проблемы, в первую очередь на ум приходят утечки памяти. Сказал, что здесь может быть фундаментальный недостаток дизайна. С другой стороны, если Car должен быть компонентом CDI, просто используйте внедрение конструктора. - person jpangamarca; 19.05.2017