在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,也许我假设错误的默认名称?
答案 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