Используйте инъекции в пользовательской области

Можно ли использовать @SessionScoped бин как поле в контексте пользовательской области?

Я пишу пользовательскую область видимости ("ScreenScoped") с помощью CDI, так что она примерно так же ведет себя, как и CDI @ViewScoped (Я делаю это, потому что последний не является WebSphere-совместимым). Пока что моя сфера действия выглядит как @ApplicationScoped было бы. Я хотел бы использовать мой @SessionScoped NavigationHandler класс, который вызывается каждый раз, когда пользователь нажимает на ссылку или кнопку, чтобы определить, когда заканчивается мой жизненный цикл ScreenScoped. Однако я получаю сообщение об ошибке при попытке использовать @Injectпод ред.

public class ScreenContext
    implements Context
{
    @Inject
    private NavigationHandler navigationHandler;
    ...
}

Из-за этого появляется исключение NullPointerException @Inject:

16:55:07,492 SEVERE [javax.enterprise.resource.webcontainer.jsf.application] (http-localhost/127.0.0.1:8443-10) Error Rendering View[/page/hello.xhtml]: javax.el.ELException: /page/hello.xhtml @24,58 visible="#{helloController.popupshowed}": java.lang.NullPointerException

...

Caused by: java.lang.NullPointerException
    at com.mypackage.scope.screenscope.ScreenContext.get(ScreenContext.java:38) [myproject.jar:]

В строке 38 я впервые вызываю введенное поле:

System.out.println("Navigation is used: " + navigationHandler.getUserId());

1 ответ

Решение

Вы не можете ввести Бин в Context, Вам нужно использовать BeanManager чтобы получить доступ к NavigationHandler боб.

Ваш контекст зарегистрирован через расширение CDI AfterBeanDiscovery событие жизненного цикла CDI. Вот здесь вы проходите BeanManager к контексту:

public void afterBeanDiscovery (@Observes final AfterBeanDiscovery event, final BeanManager beanManager)
{
    event.addContext(new ScreenContext(beanManager));
}

И тогда в вашем ScreenContext Реализация вы можете получить NavigationHandler боб (в myMethod ниже) используя BeanManager:

public class ScreenContext implements Context
{

   private final BeanManager m_beanManager;

   public ScreenContext(final BeanManager p_BeanManager)
   {
      m_beanManager = p_BeanManager;
   }

   public void myMethod()
   {
      NavigationHandler NavigationHandlerBean = getNavigationHandler();
      ...
      ...
   }

   private NavigationHandler getNavigationHandler()
   {
      final Set<Bean<?>> beans = m_beanManager.getBeans(NavigationHandler.class);
      final Bean<?> bean = m_beanManager.resolve(beans);

      return (NavigationHandler) m_beanManager.getReference(bean, NavigationHandler.class, m_beanManager.createCreationalContext(bean));
   }
Другие вопросы по тегам