Как вы находите CDI beans of/в текущем представлении (области)?

В среде Java EE 6, CDI 1.1.x, Seam 3 и т.д. нам нужно найти все CDI beans текущего вида (@ViewScoped). До сих пор я пытался использовать:

@Named
@ViewScoped
public class ViewHelper
{
    @Inject
    private BeanManager beanManager;

    public doSomethingWithTheBeanInstances()
    {
        Set<Bean<?>> beans = this.getBeanManager().getBeans( 
            Object.class, new AnnotationLiteral<Any>(){}
        );

        // do something
        ...
    }
}

Однако это возвращает все beans, которыми он управляет.

Мне нужно найти только те в рамках текущего представления и - это было бы идеально - только те, которые реализуют определенный интерфейс (унаследованный на нескольких уровнях иерархии).

Каким образом это сделать?

Обратите внимание, что поскольку CDI не имеет видимой области видимости, мы используем Seam 3, чтобы комментировать все наши объекты с видимым beans как:

@Named
@ViewScoped
public class ResultManagerColumnHandler extends BaseColumnHandler
{
    ....
}

Вышеприведенный пример - это поиск (@ViewScoped - замена CDI по Seam 3).

Как это можно сделать?

Ответ 1

Я не знаком с Seam, но с точки зрения CDI, вот что я хотел бы попробовать. Тем не менее, bean он думает, что он будет работать только, если beanManager.getContext(ViewScoped.class); возвращает действительный экземпляр контекста для вас:

@Inject
BeanManager bm;

public List<Object> getAllViewScoped() {
    List<Object> allBeans = new ArrayList<Object>();
    Set<Bean<?>> beans = bm.getBeans(Object.class);
    // NOTE - context has to be active when you try this
    Context context = bm.getContext(ViewScoped.class);

    for (Bean<?> bean : beans) {
        Object instance = context.get(bean);
        if (instance != null) {
            allBeans.add(instance);
        }
    }

    return allBeans;
}

Вы также попросили получить только beans, которые реализуют определенный интерфейс. Для этого просто измените строку кода, получив все beans с нужным типом:

Set<Bean<?>> beans = bm.getBeans(MyInterface.class);