2017-02-10 55 views
1

是否可以將@SessionScoped bean用作自定義作用域的上下文中的字段?我正在用CDI編寫一個自定義作用域(「ScreenScoped」),因此它與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豆 – Rouliboy

+1

自定義背景下通過擴展註冊,注射不能進行 – Rouliboy

回答

2

Context你不能注入一個Bean 。您需要使用BeanManager來訪問NavigationHandler bean。

您的環境通過CDI Extension註冊,觀察AfterBeanDiscovery CDI生命週期事件。這是在這裏,你通過BeanManager上下文:使用BeanManager

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

,然後在ScreenContext實現你可以得到NavigationHandler豆(以下myMethod):

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