无法在EL / Facelet中找到具有默认名称的@Named CDI bean

时间:2013-10-16 22:00:21

标签: jsf-2 el cdi

jee6 tutorial我可以阅读以下内容:

  

@Named限定符允许您通过访问bean   使用bean名称,第一个字母为小写。例如,   Facelets页面将bean称为打印机。

     

您可以指定@Named限定符的参数以使用a   非默认名称:

然而,当我尝试使用@Named而不添加参数时,找不到我的bean,我得到如下的异常。

@Named
@ViewScoped
public class MTestBean {
...
}

异常;

javax.servlet.ServletException: /MyPage.xhtml @15,65 listener="#{mTestBean.init}": Target Unreachable, identifier 'mTestBean' resolved to null

但如果我使用

@Named("mTestBean")

一切正常。这是预期的行为吗?有没有办法可以列出EL中可用的bean,也许我假设错误的默认名称?

1 个答案:

答案 0 :(得分:6)

你实际上必须使用#{MTestBean.xxx}来引用bean。有趣的是,NetBeans对默认名称做出了相同的假设,并将使用#{mTestBean.xxx}自动完成。正如BalusC指出的那样,这种命名行为遵循JavaBeans规范。从第8.8节 -

  

...支持偶尔使用所有   大写名称,我们检查如果名称的前两个字符都是大写和if   所以不管它。所以,例如,   “FooBah”成为“fooBah”   “Z”变为“z”   “网址”变为“网址”   我们提供了一个实现此转换规则的方法Introspector.decapitalize。

就使用CDI列出可用bean而言,最好的选择是javax.enterprise.inject.spi.BeanManager。见link

编辑:这是从链接稍微修改的版本,以显示EL名称,而不仅仅是类。

public void listAllBeans() throws NamingException{
        //Get the BeanManager
        InitialContext initialContext = new InitialContext();
        BeanManager bm = (BeanManager) initialContext.lookup("java:comp/BeanManager");

        //List all CDI Managed Beans and their EL-accessible name
        Set<Bean<?>> beans = bm.getBeans(Object.class,new AnnotationLiteral<Any>() {});
        for (Bean<?> bean : beans) {
            System.out.println(bean.getBeanClass().getName() + " / bean name = " + bean.getName());
        }
    }

我们的测试bean的输出 -

  

com.xxx.jsf.beans.MTestBean / bean name = MTestBean