支持bean(@ManagedBean)或CDI Beans(@Named)?

Mat*_*all 106 jsf java-ee cdi jsf-2

我刚开始阅读Core JavaServer Faces,第3版.他们这样说(强调我的):

对于可以在JSF页面中使用的bean,有两种不同的机制,CDI bean和JSF托管bean,这是一个历史事故.我们建议您使用CDI bean,除非您的应用程序必须在像Tomcat这样的普通servlet运行器上运行.

为什么?他们没有提供任何理由.我一直在使用@ManagedBean在GlassFish 3上运行的原型应用程序中的所有bean,我还没有发现任何问题.我不介意迁移@ManagedBean@Named,但我想知道为什么我应该打扰.

Bal*_*usC 168

使用CDI.

按照JSF 2.3,@ManagedBean弃用.另见规范问题1417.这意味着没有理由选择@ManagedBean结束@Named.这首先在Mojarra 2.3.0 beta版m06中实现.

在此输入图像描述


历史

核心区别在于,@ManagedBean由JSF框架管理,并且只能通过@ManagedProperty另一个JSF托管bean使用.@Named通过经由CDI框架应用服务器(容器)进行管理,是通过@Inject提供给任何类型的一个容器管理伪影的像@WebListener,@WebFilter,@WebServlet,@Path,@Stateless,等,甚至JSF @ManagedBean.从另一个侧面上,@ManagedProperty没有内部的工作@Named或任何其他容器管理的神器.它真的只在里面工作@ManagedBean.

另一个不同之处在于,CDI实际上会在每个请求/线程的基础上注入委托给目标作用域中当前实例的代理(就像EJB的注入方式一样).这种机制允许在更广泛范围的bean中注入范围更窄的bean,这是JSF无法实现的@ManagedProperty.JSF直接通过调用setter来"注入"物理实例(这也正是为什么需要setter的原因,而这不是必需的@Inject).

虽然不是直接的缺点 - 还有其他方式 - 范围@ManagedBean仅限于此.从另一个角度来看,如果你不想公开"太多" @Inject,你也可以保留你的托管bean @ManagedBean.这就像protected对抗public.但这并不重要.

至少在JSF 2.0/2.1中,CDI管理JSF支持bean的主要缺点是没有相应的CDI @ViewScoped.该@ConversationScoped接近,但仍需要手动启动和停止,并追加一个丑陋的cid请求参数的URL的结果.MyFaces CODI通过完全透明地将JSF桥javax.faces.bean.ViewScoped接到CDI 使得它更容易@Named @ViewScoped,但是你可以这样做,但是它会windowId在结果URL上添加一个丑陋的请求参数,也可以在普通的页面到页面导航上添加.OmniFaces使用真正的CDI解决了这一问题,@ViewScoped它真正将bean的范围与JSF视图状态联系起来,而不是与任意请求参数相关联.

JSF 2.2(在这个问题/答案之后3年发布)提供了一个新的完全兼容CDI的@ViewScoped注释javax.faces.view.ViewScoped.JSF 2.2甚至还附带了一个CDI @FlowScoped,它没有@ManagedBean相应的,因此推动JSF用户使用CDI.期望的是,@ManagedBean朋友将根据Java EE 8弃用.如果您目前仍在使用@ManagedBean,因此强烈建议切换到CDI以备将来的升级路径.CDI可以在Java EE Web Profile兼容容器中使用,例如WildFly,TomEE和GlassFish.对于Tomcat,您必须单独安装它,就像您为JSF所做的那样.另请参见如何在Tomcat中安装CDI?

  • 我创建了`beans.xml`,将`@ManagedBean`转换为`@ Named`,并将`@ ManagedProperty`转换为`@Inject`.一切都与世隔绝.但是,如果我将`@ EJB`注释更改为`@Inject`,则部署失败(`org.jboss.weld.exceptions.DeploymentException`),消息为"WELD-001408注入点具有不满足的依赖性".我是否真的应该使用`@Inject`将无接口EJB注入`@ Named` bean,还是应该坚持使用`@EJB`?EJB封装在EJB JAR中,与包含我的CDI bean的WAR在同一个EAR中. (4认同)

Boz*_*zho 63

CDI优于普通JSF,因为CDI允许JavaEE范围的依赖注入.您也可以注入POJO并管理它们.使用JSF,您只能使用CDI注入一部分内容.

  • @KorayTugay自2011年6月以来我没有触及过这段代码,但是我已经切换到了CDI并且工作得很好.如果您有这些问题,我很乐意回答您的任何具体问题. (5认同)
  • @MattBall Matt在你们这么多年之后,你能评论一下这次迁移吗? (3认同)

h2m*_*mch 14

使用Java EE 6和CDI,您可以使用Managed Beans的不同选项

  • @javax.faces.bean.ManagedBean是指JSR 314,随JSF 2.0引入.主要目标是避免faces-config.xml文件中的配置在JSF页面中使用bean.
  • @javax.annotation.ManagedBean(“myBean”) 由JSR 316定义.它概括了JSF托管bean以供Java EE中的其他地方使用
  • @javax.inject.Named(“myBean”) 几乎与上面的一样,除了你需要web/WEB-INF文件夹中的beans.xml文件来激活CDI.

  • 不,使用JavaEE7,您不再需要beans.xml.请参阅https://docs.oracle.com/javaee/7/tutorial/doc/cdi-adv001.htm (2认同)