支持豆(@managedBean)或CDI豆(@Named)?
题
我刚刚开始阅读 核心Javaserver面孔,第三版。 他们这么说(强调我的):
这是一个历史性的事故,有两种独立的机制:CDI豆和JSF托管豆,用于在JSF页面中使用的豆类。 我们建议您使用CDI豆 除非您的申请必须在诸如Tomcat之类的普通servlet跑步者上使用。
为什么?他们不提供 任何 理由。我一直在使用 @ManagedBean
对于在Glassfish 3上运行的原型应用程序中的所有豆子,我并没有真正注意到此问题。我不特别介意从 @ManagedBean
到 @Named
, ,但我想知道 为什么我应该打扰.
解决方案
CDI优于普通JSF,因为CDI允许在Javaee范围内注射。您还可以注入Pojos,并让它们进行管理。使用JSF,您只能向CDI注入一个子集。
其他提示
使用CDI。
根据JSF 2.3, @ManagedBean
是 弃用. 。也可以看看 规格问题1417. 。这意味着没有再选择的理由 @ManagedBean
超过 @Named
. 。这首先在Mojarra 2.3.0 Beta版本M06中实施。
历史
核心区别是, @ManagedBean
由JSF框架管理,仅通过 @ManagedProperty
可用于另一个JSF托管豆。 @Named
由应用程序服务器(容器)通过CDI框架管理,并且可以通过 @Inject
可用于任何类型的容器托管工件 @WebListener
, @WebFilter
, @WebServlet
, @Path
, @Stateless
, ,等等,甚至是JSF @ManagedBean
. 。从另一侧, @ManagedProperty
做 不是 在内部工作 @Named
或任何其他容器托管工件。它实际上只能在内部工作 @ManagedBean
.
另一个区别是,CDI实际上以每次要求/线程为基础将当前实例委派给当前实例(例如如何注入EJB)。这种机制允许在更宽的范围中注入较窄范围的豆子,而JSF不可能 @ManagedProperty
. 。 JSF“注入”此处直接通过调用设置器直接进行物理实例(这也是为什么需要设置器的原因,而这是为什么 不是 需要 @Inject
).
虽然不是直接的劣势 - 还有其他方法 - @ManagedBean
只是有限的。从另一个角度来看,如果您不想暴露“太多” @Inject
, ,您也可以保留托管的豆类 @ManagedBean
. 。就像是 protected
相对 public
. 。但这并不重要。
至少在JSF 2.0/2.1中,CDI管理JSF支持豆的主要缺点是没有CDI等同于 @ViewScoped
. 。这 @ConversationScoped
接近,但仍然需要手动开始和停止,并且附加了一个丑陋的 cid
请求参数以结果URL。 Myfaces Codi通过完全透明地桥接JSF使其更容易 javax.faces.bean.ViewScoped
到CDI,所以您可以做 @Named @ViewScoped
, 但是,这添加了一个丑陋的 windowId
请求参数以结果URL,也可以在Plain Vanilla页面到页面导航上。 综合 用真正的CDI解决这一切 @ViewScoped
它确实将BEAM的范围与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配置文件中兼容的容器,例如Wildfly,Tomee和Glassfish。对于Tomcat,您必须单独安装它,就像您对JSF已经做的一样。也可以看看 如何在Tomcat中安装CDI?
使用Java EE 6和CDI,您有不同的选择托管豆
@javax.faces.bean.ManagedBean
请参考JSR 314,并用JSF 2.0引入。主要目标是避免在faces-config.xml文件中使用bean在JSF页面中。@javax.annotation.ManagedBean(“myBean”)
由JSR 316定义。它概括了JSF托管豆,用于Java EE中的其他位置@javax.inject.Named(“myBean”)
与上述一个几乎相同,除了您需要Web/Web-Inf文件夹中的beans.xml文件以激活CDI。
我当时在Glassfish 3.0.1中使用CDI,但是要使它起作用,我必须进口Seam 3框架(焊缝)。效果很好。
在Glassfish 3.1中,CDI停止工作,接缝焊缝停止使用。我打开了 这是错误的 但还没有看到它修复。我必须将所有代码转换为使用javax.faces。
我同意您应该使用CDI,但是我尚未看到解决的一个问题是如何处理@ViewScoped注释。我有很多代码取决于它。尚不清楚@ViewScoped如果您不使用@managedBean,是否有效。如果有人能澄清这一点,我将不胜感激。
转移到CDI的一个充分理由:您可以拥有一个常见的会话资源(例如用户配置文件) @Inject
''介入JSF托管豆类和休息服务(即,泽西岛/JAX-RS)。
另一方面, @ViewScoped
是坚持使用JSF的令人信服的理由 @ManagedBean
- 特别是对于具有重要AJAX的任何东西。 CDI中没有标准替代品。
似乎它可能支持 @ViewScoped
- 类似CDI豆的注释,但我没有亲自玩。