2017-02-10 10 views
1

beanをカスタムスコープのコンテキストのフィールドとして使用できますか?カスタムスコープでの注入の使用

私はCDIのカスタムスコープ( "ScreenScoped")を作成していますので、CDIの@ViewScopedとほぼ同じ動作をします(後者はWebSphereと互換性がないためです)。これまでのところ私の範囲は@ApplicationScopedのようになります。 @SessionScoped NavigationHandlerクラスを使用したいと思います。これは、ユーザーがリンクやボタンをクリックするたびに呼び出され、ScreenScopedのライフサイクルが終了するタイミングを決定します。しかし、私は@Injectエドフィールドを使用しようとするとエラーが発生します。

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

A 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は、私が注入されたフィールドを呼び出す最初の時間です:あなたはContextで豆を注入することはできません

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

使用BeanManager:BeanManagerを使用して(以下myMethodに)

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

そしてあなたScreenContext実装では、あなたがNavigationHandler Beanを取得することができます:それはあなたがコンテキストにBeanManagerを渡すことをここですNavigationHandler bean – Rouliboy

+1

カスタムコンテキストがExtension経由で登録されているため、注入は実行できません – Rouliboy

答えて

2

を。 bean NavigationHandlerにアクセスするには、BeanManagerを使用する必要があります。

あなたのコンテキストは、CDI拡張を介して登録されており、CDIライフサイクルAfterBeanDiscoveryイベントを監視しています。取得する

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であっても、このメソッドは2つの異なるブラウザから呼び出されたときに常に同じオブジェクトを返します。 – Vulpo

+0

私のコメントは次の投稿で解決された別の問題によるものですので、私はあなたの答えを再度受け入れました:http://stackoverflow.com/questions/42256767/beanmanager-always-returns-same-reference – Vulpo

+0

君は :-) – Rouliboy

関連する問題