2014-11-05 1 views
1

Ниже приведен код, который я использую для вставки контекстных компонентов CDI в объект без контекста.Правильный способ ввода CDI Контекстные компоненты в существующий неконтекстный компонент?

// 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); 

Код для Destroy 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, поэтому мне не нужно жет код уничтожить контроллер и код, он предложил, как показано ниже:

// 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 для получения ссылок на него? –

ответ

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 для достижения той же цели, что и Unmanaged. Вы можете даже использовать шаблон фабрики, чтобы делегировать часть работы. Поддержка у вас есть этот момент впрыска:

@Inject @Any 
private Instance<MyController> myControllerProvider; 

в методе бизнеса, когда вам нужна ссылка, вы можете сделать

MyController controller = myControllerProvider.get(); 

Который даст вам удались ссылка. Однако я заметил, что вы используете статический класс - это означает, что он не является классом верхнего уровня. CDI потребует его как класса верхнего уровня.

+0

Я только что обновил. Удалить статическое ключевое слово. Еще одна причина, по которой я сам создаю контроллер, - это экземпляр контроллера, созданный в методе, поэтому его жизненный цикл - это жизненный цикл метода. – Loc

Смежные вопросы