简体   繁体   English

在SystemEventListener中注入CDI托管bean

[英]Inject CDI managed bean in SystemEventListener

I have used answer of How to disable elements from within a ViewHandler after jsf has embedded the composite component? 我已经使用了jsf嵌入复合组件后如何从ViewHandler中禁用元素的答案 to programmatically disable all components in all forms. 以编程方式禁用所有形式的所有组件。 A SystemEventListener catches and disables all components. SystemEventListener捕获并禁用所有组件。

What I would like to add is getting some logic from a CDI bean. 我想添加的是从CDI bean获得一些逻辑。 It appears that I cannot @Inject a CDI bean inside SystemEventListener . 看来我不能在SystemEventListener内部@Inject CDI bean。 Is there some other mechanism to get logic from CDI beans? 还有其他一些机制可以从CDI bean获得逻辑吗? I have lots of components and it would be very time consuming to add disabled="#{bean.disabled}" to all components. 我有很多组件,向所有组件添加disabled="#{bean.disabled}"会非常耗时。 As I understand this is the right approach to "batch disable" or I'm heavily mistaken here? 据我了解,这是“批量禁用”的正确方法,还是我在这里很误会?

It seems that you're not using JSF 2.2 yet. 看来您尚未使用JSF 2.2。 Since that version, a lot of JSF artifacts have been made eligible for CDI injection, including SystemEventListener instances. 从该版本开始,已经使许多JSF工件可以进行CDI注入,包括SystemEventListener实例。 See also What's new in JSF 2.2? 另请参见JSF 2.2的新增功能? - Issue 763 . -问题763 If you're running JSF 2.0/2.1 on a Servlet 3.0 capable container, then it should be a minimum of effort to upgrade to JSF 2.2. 如果要在支持Servlet 3.0的容器上运行JSF 2.0 / 2.1,那么升级到JSF 2.2的工作量应该最少。

If you can't upgrade for some reason, then you can always programmatically grab the CDI managed bean via JNDI. 如果由于某种原因而无法升级,则始终可以通过JNDI以编程方式获取CDI托管bean。 The CDI BeanManager instance is available at JNDI name java:comp/BeanManager . CDI BeanManager实例以JNDI名称java:comp/BeanManager可用。 Once having it at hands, use the below getReference() utility method to obtain the reference of interest. 一旦掌握了它,就可以使用下面的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));
}

(source code from OmniFaces Beans / BeansLocal ) (源代码来自OmniFaces Beans / BeansLocal

So, in a nutshell: 因此,简而言之:

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

Or, if you're already using OmniFaces 1.x, or are open to using it, use its Beans utility class (available since 1.6 only): 或者,如果您已经在使用OmniFaces 1.x,或者愿意使用它,请使用其Beans实用程序类(仅从1.6开始可用):

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

Both return a proxy reference, you could safely assign it as an instance variable of the SystemEventListener class during its construction. 两者都返回一个代理引用,您可以在构造期间安全地将其分配为SystemEventListener类的实例变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM