4

jee6 教程中,我可以阅读以下内容:

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

您可以为 @Named 限定符指定一个参数以使用非默认名称:

但是,当我尝试在不添加参数的情况下使用 @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,也许我假设错误的默认名称?

4

1 回答 1

6

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

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

至于使用 CDI 列出可用的 bean,最好的选择是 javax.enterprise.inject.spi.BeanManager。看到这个链接

编辑:这是一个从链接略微修改的版本,以显示 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 / 豆名 = MTestBean

于 2013-10-17T13:27:32.803 回答