在SystemEventListener中注入CDI管理bean



我已经使用了如何在jsf嵌入复合组件后从ViewHandler中禁用元素的答案?以编程方式禁用所有窗体中的所有组件。SystemEventListener捕获并禁用所有组件。

我想添加的是从CDI bean获取一些逻辑。看来我不能在SystemEventListener@Inject一个CDI bean。是否有其他机制从CDI bean获取逻辑?我有很多组件,将disabled="#{bean.disabled}"添加到所有组件将非常耗时。据我所知,这是"批量禁用"的正确方法,还是我在这里犯了严重的错误?

看起来您还没有使用JSF 2.2。从那个版本开始,很多JSF构件都符合CDI注入的条件,包括SystemEventListener实例。参见JSF 2.2有哪些新特性?-第763期。如果您在一个支持Servlet 3.0的容器上运行JSF 2.0/2.1,那么升级到JSF 2.2应该是最简单的工作。

如果由于某种原因无法升级,那么您总是可以通过JNDI以编程方式获取CDI托管bean。CDI BeanManager实例的JNDI名称为java:comp/BeanManager。一旦有了它,使用下面的getReference()实用程序方法来获得感兴趣的引用。

public static <T> T getReference(BeanManager beanManager, Class<T> beanClass) {
    Bean<T> bean = resolve(beanManager, beanClass);
    return (bean != null) ? getReference(beanManager, bean) : null;
}
public static <T> Bean<T> resolve(BeanManager beanManager, Class<T> beanClass) {
    Set<Bean<?>> beans = beanManager.getBeans(beanClass);
    for (Bean<?> bean : beans) {
        if (bean.getBeanClass() == beanClass) {
            return (Bean<T>) beanManager.resolve(Collections.<Bean<?>>singleton(bean));
        }
    }
    return (Bean<T>) beanManager.resolve(beans);
}
public static <T> T getReference(BeanManager beanManager, Bean<T> bean) {
    return (T) beanManager.getReference(bean, bean.getBeanClass(), beanManager.createCreationalContext(bean));
}

(源代码来自OmniFaces Beans/BeansLocal)

所以,简单地说:

BeanManager beanManager = (BeanManager) new InitialContext().lookup("java:comp/BeanManager");
YourBean yourBean = getReference(beanManager, YourBean.class);
// ...

或者,如果你已经在使用OmniFaces 1。或者您愿意使用它,请使用它的Beans实用程序类(仅从1.6开始可用):

YourBean yourBean = Beans.getReference(YourBean.class);
// ...

都返回一个代理引用,您可以在SystemEventListener类的构造过程中将其安全地分配为实例变量。

相关内容

  • 没有找到相关文章

最新更新