CDI Transactional Interceptor не работает с CDI Producer

У меня есть похожая проблема, описанная в этом сообщении:

Но мне нужно использовать метод производителя для создания сложного объекта (этот объект получает два параметра в конструкторе). Использование метода производителя для потери ссылки на перехватчик. Я ничего не нашел в спецификации CDI, где бы говорилось, что перехватчики не выполняются над объектами, сгенерированными методами производителя.

Мой вопрос: возможно ли использовать метод производителя и сохранить ссылку с перехватчиками?


person Luciano    schedule 05.11.2015    source источник
comment
Если у вас такая же проблема, ответ на другой вопрос должен отвечать на ваш. Если у вас другая проблема, пожалуйста, опубликуйте фрагменты кода, что вы пробовали и какие ошибки вы получаете, чтобы помочь людям ответить на ваш вопрос. Поскольку это ваш вопрос, очень трудно ответить. См. также stackoverflow.com/help/how-to-ask.   -  person Buurman    schedule 05.11.2015
comment
Я редактирую вопрос, чтобы очистить его.   -  person Luciano    schedule 05.11.2015


Ответы (1)


Перехватчики и декораторы CDI применяются только к bean-компонентам, экземпляры которых создаются контейнером CDI.

Однако есть уродливый обходной путь. Это немного технично, но потерпите меня. Я пишу это в основном без IDE, поэтому прошу прощения за опечатки и тому подобное, просто чтобы дать вам представление.

Сначала вам нужно создать квалификатор

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD, ElementType.PARAMETER})
public @interface InjectionParameter {
    int value();
}

Затем вам нужно будет аннотировать свой специальный конструктор следующим образом:

@Inject
public MyClass(@InjectionParameter(1) Object firstParam, @InjectionParameter(2) Object secondParameter)

Тогда для вашего продюсера вы говорите

@Inject
private Instance<MyClass> myClassInstance;

@Produces
@InjectionParameter(1)
Object firstParam;

@Produces
@InjectionParameter(2)
Object secondParam;

@Produces MyClass producer() {
    firstParam = null; /* set your first param here */
    secondParam = null; /* set your second param here */
    return myClassInstance.get();
}

Обратите внимание, что мое использование Object было просто примером, пожалуйста, замените ваши собственные фактические типы :)

Дело в том, что контейнер CDI МОЖЕТ создавать экземпляры bean-компонентов, у которых нет конструктора по умолчанию, если правильный конструктор аннотирован @Inject и каждый параметр является допустимой целью внедрения. Что я там сделал, так это настроил параметры вашего bean-компонента через поля производителя.

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

Надеюсь это поможет. -Юусо

person jvalli    schedule 09.11.2015