支持豆(@ManagedBean)或CDI豆(@Named)?
我刚刚开始阅读通过核心JavaServer Faces,第三版。 他们说这个(重点是我的):
对于可以在JSF页面中使用的bean,有两个单独的机制,即CDI bean和JSF managed beans,这是一个历史性的意外。 我们build议您使用CDI bean,除非您的应用程序必须使用纯粹的servlet运行程序(如Tomcat)。
为什么? 他们没有提供任何理由。 我在GlassFish 3上运行的原型应用程序中的所有bean都使用了@ManagedBean
,而且我还没有真正注意到这个问题。 我不特别介意从@ManagedBean
迁移到@Named
,但是我想知道为什么我应该打扰 。
CDI比普通的JSF更受欢迎,因为CDI允许JavaEE范围内的dependency injection。 你也可以注入POJO并让它们被pipe理。 使用JSF,你只能注入CDI的一部分。
使用CDI。
根据JSF 2.3,@ @ManagedBean
已被弃用 。 另请参阅规格问题1417 。 这意味着没有理由select@ManagedBean
不是@Named
。 这是在Mojarra 2.3.0 beta版本m06中首次实现的。
历史
核心的区别在于,@ @ManagedBean
由JSF框架pipe理,只能通过@ManagedProperty
提供给另一个JSFpipe理的bean。 @Named
由应用程序服务器(容器)通过CDI框架进行pipe理,并通过@Inject
可用于任何种类的容器pipe理的工件,如@WebListener
, @Stateless
@WebListener
, @Stateless
@WebListener
, @Stateless
@WebListener
, @Stateless
等,甚至JSF @ManagedBean
。 另一方面,@ @ManagedProperty
在@Named
或任何其他容器pipe理的工件中不起作用。 它真的只在@ManagedBean
。
另一个区别是,CDI实际上是在每个请求/线程的基础上(比如如何注入EJB),在目标范围内注入委托给当前实例的代理。 这种机制允许在更广泛的bean中注入更窄范围的bean,这对于JSF @ManagedProperty
是不可能的。 JSF通过调用setter直接在这里注入物理实例(这也正是为什么需要setter,而@Inject
不需要)。
虽然不是直接的缺点 – 还有其他的方法 – @ManagedBean
的范围是有限的。 从另一个angular度来看,如果你不想为@Inject
公开“太多”,你也可以保留你的托pipebean @ManagedBean
。 这就像protected
与public
。 但是这不算真正的数字。
至less,在JSF 2.0 / 2.1中,CDIpipe理JSF支持bean的主要缺点是没有CDI相当于@ViewScoped
。 @ConversationScoped
接近,但仍需要手动启动和停止,并将丑陋的cid
请求参数附加到结果URL。 通过将JSF的javax.faces.bean.ViewScoped
完全透明地桥接到CDI,MyFaces CODI使得它更容易,因此您可以执行@Named @ViewScoped
,但是它会在结果URL上附加一个丑陋的windowId
请求参数,也会在普通的vanilla页面间导航。 OmniFaces通过一个真正的CDI @ViewScoped解决了这个问题,它真正将bean的范围连接到JSF视图状态,而不是任意的请求参数。
JSF 2.2(在这个问题/答案之后的3年发布)提供了一个新的完全兼容CDI的@ViewScoped
注解, javax.faces.view.ViewScoped
。 JSF 2.2甚至还带有一个只@FlowScoped
CDI的@FlowScoped
,它没有一个@ManagedBean
等价物,从而把JSF用户推向了CDI。 期望的是@ManagedBean
和朋友将被弃用,按照Java EE 8。如果您目前仍在使用@ManagedBean
,那么强烈build议切换到CDI以备将来的升级途径。 CDI随时可用于Java EE Web Profile兼容容器,如WildFly,TomEE和GlassFish。 对于Tomcat,您必须单独安装它,就像您已经为JSF做的一样。 另请参见如何在Tomcat中安装CDI?
使用Java EE 6和CDI,您可以select托pipe豆
-
@javax.faces.bean.ManagedBean
是指JSR 314,并且是与JSF 2.0一起引入的。 主要目标是避免faces-config.xml文件中的configuration在JSF页面中使用bean。 -
@javax.annotation.ManagedBean(“myBean”)
由JSR 316定义。它概括了JSFpipe理的bean,供在Java EE中使用 -
@javax.inject.Named(“myBean”)
几乎与上面的一样,只是在web / WEB-INF文件夹中需要一个beans.xml文件来激活CDI。
我在GlassFish 3.0.1中使用了CDI,但为了使它工作,我不得不导入Seam 3框架(焊接)。 这工作得很好。
在GlassFish 3.1中,CDI停止工作,Seam Weld停止工作。 我打开了一个错误,但还没有看到它修复。 我不得不将所有的代码转换为使用javax.faces。*注释,但是我打算一旦它们工作就回到CDI。
我同意你应该使用CDI,但是我还没有看到的一个问题是如何处理@ViewScoped注释。 我有很多依赖于它的代码。 不清楚@ViewScoped是否工作,如果你没有使用@ManagedBean。 如果有人能澄清这一点,我将不胜感激。
转移到CDI的一个很好的理由是:您可以在JSF托pipe的bean和REST服务(即Jersey / JAX-RS)中拥有一个通用的会话范围资源(例如用户configuration文件) @Inject
。
另一方面, @ViewScoped
是坚持使用JSF @ManagedBean
的强有力的理由 – 特别是对于任何具有重要AJAX的东西。 CDI没有这个标准的替代品。
似乎它可能有一些支持类似@ViewScoped
的CDI bean的注释,但是我没有亲自玩过它。