如何在当前视图(范围)中找到 CDI bean?

Kaw*_*awu 5 jsf cdi seam3 view-scope jakarta-ee

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
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,这会返回它管理的所有bean。

我只需要找到当前视图范围内的那些,并且 - 这将是理想的 - 只找到那些实现特定接口(在多个层次结构级别上继承)的接口。

有什么方法可以做到呢?

请注意,由于 CDI 没有视图范围,因此我们使用Seam 3来注释所有视图范围的 bean,例如:

@Named
@ViewScoped
public class ResultManagerColumnHandler extends BaseColumnHandler
{
    ....
}
Run Code Online (Sandbox Code Playgroud)

上面是一个需要寻找的实例(它@ViewScoped是 Seam 3 的 CDI 替代品)。

如何做呢?

Sil*_*rus 3

我不熟悉 Seam,但从 CDI 的角度来看,这就是我会尝试的。但是,请记住,只有在为您返回有效的上下文实例时它才会起作用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;
}
Run Code Online (Sandbox Code Playgroud)

您还要求仅获取实现特定接口的 bean。为此,只需修改代码行即可检索具有所需类型的所有 bean:

Set<Bean<?>> beans = bm.getBeans(MyInterface.class);
Run Code Online (Sandbox Code Playgroud)