2015-02-10 2 views
3

Хотя я нашел примеры в CDI, где вы установили @Produces (вроде фабричной фабрики) или используя концепции CDI javax.enterprise.inject.spi.Unmanaged, все они, кажется, предполагают что CDI будет тем, который создает экземпляр класса на его собственных условиях и жизненном цикле (что имеет смысл).Как настроить компонент non-CDI от стороннего участника для @Inject в CDI bean

Однако существуют ситуации, когда CDI просто не может создать экземпляр.

Например, сторонняя библиотека (которая не использует сам CDI), которая создает объект внутри и передает его вам.

Теперь, как я могу взять эти уже созданные объекты (которые, кстати, являются конечными объектами без конструктора по умолчанию) и сделать их доступными для моих управляемых бинов CDI, чтобы затем использовать?

Вот упрощенный пример.

public class Foo 
{ 
    @Inject 
    private ByteBuffer buf; 

    public void go() 
    { 
     // do something, with buffer 
    } 
} 

public void process() { 
    ByteBuffer buf = ByteBuffer.allocate(500); 
    // TODO: how to add "buf" to current context? 
    Foo foo = CDI.current().select(Foo.class,AnyLiteral.INSTANCE).get(); 
    foo.go(); 
} 

Теперь я понимаю, что для этого конкретного Например, я мог eaily просто передать в ByteBuffer или установки в @Produces для ByteBuffer, или даже Foo сделать сам ByteBuffer. (все это было бы проще). Я выбрал ByteBuffer, потому что он обладает теми же проблемами я столкнулся с библиотекой 3-й партии

  • экземплярами являются действительными бобами
  • я не имею никакого контроля над своим источником
  • Экземпляры создаются с помощью библиотеки
  • Эти экземпляры final и не могут быть обернуты, переопределены, или проксированном

случай использования также имеет ситуации, в которых имеются вложенные ссылки CDI, которые могли бы также использовать в соотв ess для этого @Inject ByteBuffer buf;.

В идеале было бы желательно, чтобы это была чистая техника CDI api, а не что-то, что связано с сваркой или реализацией.

Я devled в пользовательское создание Scope, а также, думая, что может быть решением для этого, имея вид @BufferScope, который идентифицирует start() и end() этого экземпляр. Но ни один из примеров и документации не делает этого очень ясным в отношении объектов, которые CDI просто не может назвать newInstance() или produce(). Реализация объекта из моих рук, но возможность представить его в области CDI возможно, а также даже управлять окончательной смертью/уничтожением этого экземпляра.

+1

Извините, но я не понимаю, в чем ограничение '@ Produces', что заставляет вас это делать. –

ответ

1

Proxying - это не то же самое, что и упаковка. Обычным обходным решением является создание ByteBufferHolder (вставьте здесь свой класс), который адаптирует поток настраиваемого строителя к компоненту, который понимает, что он находится внутри контекста DI.

+0

Я предполагаю, что ваш «в bean» относится к CDI 'javax.enterprise.inject.spi.Bean', так что правильный способ получить действительную ссылку CDI Bean после того, как у вас есть экземпляр, все методы, похоже, предположим, что вы начинаете с класса, и экземпляр приходит позже благодаря CDI. (угадайте, что я прошу, это пример, или точка javadoc, которую я просто пропустил) –

1

Я не уверен, что согласен с оригинальным утверждением, что CDI предполагает, что он создает экземпляры. Например, я использую следующие в приложении JSF, чтобы впрыснуть текущий FacesContext экземпляр ....

import javax.enterprise.context.RequestScoped; 
import javax.enterprise.inject.Produces; 
import javax.faces.context.FacesContext; 

public class FacesContextProducer { 

    @Produces @RequestScoped FacesContext getFacesContext() { 
     return FacesContext.getCurrentInstance(); 
    } 
} 

В нигде я создаю экземпляр FacesContext. Все, что требуется, - это то, что было создано внешней инфраструктурой.

Итак, если есть внешний источник, из которого вы получаете экземпляры, до тех пор, пока вы можете получить правильный, подход @Produces должен работать?

0

Здесь есть некоторые фундаментальные недоразумения. CDI не требуется для создания экземпляров компонента, которые он может выполнять с помощью методов производителя. Зависимая область действия будет отлично работать, если класс не является проксибельным. Вы также можете создать класс-оболочку для объекта и поместить указанные экземпляры классов в любую область, в которой вы нуждаетесь.

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