2014-11-05 55 views
1

以下是我用來將CDI上下文bean注入非上下文對象的代碼。將CDI上下文bean注入到現有非上下文bean中的正確方法?

// My controller is Non-contextual bean 
    public class MyController extends Controller { 

     @Inject 
     ModelBinder modelBinder; 

     @Inject 
     ApplicationConfig applicationConfig; 

     private CreationalContext<Controller> creationalContext; 

     public void setCreationalContext(CreationalContext<Controller> creationalContext) { 
      this.creationalContext = creationalContext; 
     } 

     public CreationalContext<Controller> getCreationalContext() { 
      return creationalContext; 
     } 

     // Other fields 
    } 

代碼來初始化myController的

// Create Non-contextual bean 
    MyController controller = new MyController(); 

    AnnotatedType<?> at = beanManager.createAnnotatedType(controller.getClass()); 
    InjectionTarget<Controller> it = (InjectionTarget<Controller>)beanManager.createInjectionTarget(at); 

    CreationalContext<Controller> creationalContext = beanManager.createCreationalContext(null); 

    // Perform inject 
    it.inject(controller, creationalContext); 

    // Store creationalContext related 
    controller.setCreationalContext(creationalContext); 

代碼來破壞myController的

// controller is instance of MyController 
    AnnotatedType<?> at = beanManager.createAnnotatedType(controller.getClass()); 
    InjectionTarget<Controller> it = (InjectionTarget<Controller>)beanManager.createInjectionTarget(at); 

    it.dispose(controller); 

    controller.getCreationalContext().release(); 

今天,我的團隊領導找我談過,他說:因爲ModelBinder的,ApplicationConfig是CDI應用程序範圍bean,所以我不需要記錄ITE代碼破壞控制器和編碼他建議象下面這樣:

// New MyController 
    public class MyController extends Controller { 

     @Inject 
     ModelBinder modelBinder; 

     @Inject 
     ApplicationConfig applicationConfig; 

     // Do not need to store creationalContext 
     //private CreationalContext<Controller> creationalContext; 

     //public void setCreationalContext(CreationalContext<Controller> creationalContext) { 
     // this.creationalContext = creationalContext; 
     //} 

     //public CreationalContext<Controller> getCreationalContext() { 
     // return creationalContext; 
     //} 

     // Other fields 
    } 

新代碼來初始化myController的

// Create Non-contextual bean 
    MyController controller = new MyController(); 

    AnnotatedType<?> at = beanManager.createAnnotatedType(controller.getClass()); 
    InjectionTarget<Controller> it = (InjectionTarget<Controller>)beanManager.createInjectionTarget(at); 

    CreationalContext<Controller> creationalContext = beanManager.createCreationalContext(null); 

    // Perform inject 
    it.inject(controller, creationalContext); 

    // Do not need to store creationalContext related 
    // controller.setCreationalContext(creationalContext); 

新代碼來破壞myController的

// No need code to destroy the controller 

任何人有什麼想法?非常感謝!

+0

我不得不問,爲什麼你甚至自己實例化控制器?爲什麼不使用CDI容器來獲取對它的引用? – 2014-11-05 17:29:14

回答

3

由於CDI 1.1,提供了Unmanaged輔助類來緩和與非上下文的情況下工作,所以,你可以寫:

Unmanaged<MyController> unmanaged = new Unmanaged<MyController>(MyController.class); 
UnmanagedInstance<MyController> instance = unmanaged.newInstance(); 
MyController controller = instance.produce().inject().postConstruct().get(); 
... // Use the controller instance 
instance.preDestroy().dispose(); 

該版本使用CDI.current()來檢索BeanManager雖然你可以提供它如果需要的話:

Unmanaged<MyController> unmanaged = new Unmanaged<MyController>(beanManager, MyController.class); 

的更多信息可以在CDI說明書中obtaining non-contextual instance找到。

0

我認爲這裏真正的問題是爲什麼你需要實例化你的控制器而不是獲取託管參考?

您可以使用@Dependent作用域bean來實現與Unmanaged正在解決的相同的事情。你甚至可以使用工廠模式來委託一些工作。支持你有這樣的注入點:

@Inject @Any 
private Instance<MyController> myControllerProvider; 

在您的業務方法,當你需要的參考,你可以做

MyController controller = myControllerProvider.get(); 

,這將給你一個託管引用。但我注意到你正在使用靜態類 - 這意味着它不是頂級類。 CDI將要求它作爲頂級課程。

+0

我剛更新。刪除靜態關鍵字。我自己創建Controller的另一個原因是在Method中創建的Controller實例,所以它的生命週期就是方法生命週期。 – Loc 2014-11-05 17:44:06

相關問題