2013-11-12 2 views
9

Я добавил PhaseListener к faces-config.xml:Как @Inject в PhaseListener

<lifecycle> 
    <phase-listener>com.project.NotificationListener</phase-listener> 
</lifecycle> 

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

public class NotificationListener implements PhaseListener { 

    @Inject 
    private MyCDIStuff stuff; 

    @Override 
    public PhaseId getPhaseId() { 
     return PhaseId.RENDER_RESPONSE; 
    } 

    @Override 
    public void beforePhase(PhaseEvent event) { 
     this.stuff.doStuff(); 
    } 
} 

Метод 'beforePhase' вызывается правильно, однако объект MyCDIStuff имеет значение NULL. Я попытался использовать аннотацию @Singleton для класса, который, скорее всего, был неправильным, и он также не делал работу с инъекциями.

Есть ли способ инъецировать управляемые бисин CDI в PhaseListener?

ответ

13

Перед тем как JSF 2.2, PhaseListener s не зарегистрированы в качестве целей для инъекций CDI. Использование @Inject@EJB) эффективно не влияет на PhaseListener с. Вам необходимо вручную захватить управляемые bean-объекты CDI, программно оценивая выражение EL, ссылающееся на имя (неявное) @Named (неявное) имя, или как последнее средство с помощью JNDI и BeanManager, которое довольно неуклюжие.

Итак, если вы не можете перейти на JSF 2.2 (который должен быть совместим с любым JSF 2.0/2.1 и сервлет 3.0 совместимым веб-приложением), то ваш лучший выбор программно оценивает выражение EL, ссылающееся на имя @Named. Если предположить, что у Вас есть

@Named("stuff") 
public class MyCDIStuff {} 

, то это следует делать:

FacesContext context = event.getFacesContext(); 
MyCDIStuff stuff = context.getApplication().evaluateExpressionGet(context, "#{stuff}", MyCDIStuff.class); 
// ... 
+1

Я проверил о JSF 2.2. и ответ был «нет», мы не можем этого сделать. Я попробую использовать @Named и получить его из FacesContext. –

4

Если вы не можете пойти JSF 2.2, вам лучше всего использовать Deltaspike Core.

предлагает MyCDIStuff myCDIStuff = BeanProvider.getContextualReference(MyCDIStuff.class, false);

Deltaspike как вы должны получить материал, а потом придумывать сами. Например, если у вас должен быть BeanManager (например, для запуска события), то ядро ​​Deltaspike также предлагает BeanManagerProvider.

http://deltaspike.apache.org/core.html

+0

Я получил ответ от BalusC на работу. Я верю, что это тоже будет сделано, но я бы предпочел не включать в проект дополнительные библиотеки, поэтому в этом случае было бы «родным» решением. –

+0

Конечно, собственное решение превосходно. Хотя Deltaspike является «дополнительной» библиотекой, это не совсем неясно. Это от парней сварщиков и сова, и у него есть некоторые действительно хорошие вещи. –

+0

. Я попытаюсь найти некоторое время, чтобы немного почитать об этом. –

Смежные вопросы