2017-02-10 19 views
1

Возможно ли использовать bean-компонент в качестве поля в контексте контекста пользовательской области @SessionScoped?Использовать инъекции в настраиваемом диапазоне

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

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()); 
+0

Используйте BeanManager, чтобы получить NavigationHandler bean – Rouliboy

+1

Поскольку пользовательский контекст зарегистрирован через Extension, инъекция не может быть выполнена – Rouliboy

ответ

2

Вы не можете впрыснуть Bean в Context , Вы должны использовать BeanManager, чтобы получить доступ к bean-компоненту 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)); 
    } 
+0

После тестирования я увидел, что даже если NavigationHandler является WindowScoped, этот метод всегда возвращает тот же объект при вызове из двух разных браузеров. – Vulpo

+0

Я снова принял ваш ответ, так как мой комментарий был вызван другой проблемой, которая была решена в следующем сообщении: http://stackoverflow.com/questions/42256767/beanmanager-always-returns-same-reference – Vulpo

+0

Рад, если это поможет вы :-) – Rouliboy