您如何在当前视图(范围)中找到 CDI bean?
Posted
技术标签:
【中文标题】您如何在当前视图(范围)中找到 CDI bean?【英文标题】:How do you find CDI beans of/in the current view (scope)? 【发布时间】:2017-06-19 22:08:03 【问题描述】:在 Java EE 6、CDI 1.1.x、Seam 3 等环境中,我们需要找到当前视图的所有 CDI bean (@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
...
但是,这会返回它管理的 所有 个 bean。
我只需要找到在当前视图范围内的那些,并且 - 这将是理想的 - 只需要那些实现特定接口(继承于多个层次结构级别)的那些。
有什么办法呢?
请注意,由于 CDI 没有视图范围,我们使用 Seam 3 来注释我们所有的视图范围 bean,例如:
@Named
@ViewScoped
public class ResultManagerColumnHandler extends BaseColumnHandler
....
上面是要查找的实例(@ViewScoped
是 Seam 3 的 CDI 替代品)。
怎么做?
【问题讨论】:
快速思考一下 - 如果您想要的所有这些 bean 都实现特定接口,那么它们具有该接口的类型,因此您可以使用@Inject Instance<YourInterfaceType> instances
。现在,因为 Instance
实现了 Iterable,您应该能够遍历所有实例。
问题仍然是如何在不知道特定 bean 名称(EL 名称和/或类名称)的情况下只获取当前视图中的那些...???
我不熟悉Seam3,但Context context = beanManager.getContext(ViewScoped.class);
是否返回有效的Context
? (即不是 null 也不是异常)。如果该部分有效,那么我可以发布一个答案如何使用它来获取当前活动的 bean。
Siliarus 偷了我的答案,但如果 Context
有效,那么它基本上可以归结为他的帖子中所示的方法。它已经在OmniFaces 中使用了很长时间(由您本人真正撰写)。
运气好吗?我的第一条评论没有得到任何反馈。至少我记得这个骗子***.com/q/33478927
【参考方案1】:
我不熟悉 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;
您还要求仅获取实现特定接口的 bean。为此,只需修改检索所有具有所需类型的 bean 的代码行:
Set<Bean<?>> beans = bm.getBeans(MyInterface.class);
【讨论】:
好的,谢谢。我在我的 IDE 中尝试了 AppScoped 的代码,但粘贴后忘记编辑这篇文章。以上是关于您如何在当前视图(范围)中找到 CDI bean?的主要内容,如果未能解决你的问题,请参考以下文章
将较短范围的 Bean 实例注入 CDI 中较大范围的 bean 实例 - 它是如何工作的?
是否在会话范围的 JSF 支持 bean 中观察到 CDI 事件