由于 CDI/Weld 中的 @Named,@ManagedBeans 在 JavaEE6 中过时了吗?

Posted

技术标签:

【中文标题】由于 CDI/Weld 中的 @Named,@ManagedBeans 在 JavaEE6 中过时了吗?【英文标题】:Are @ManagedBeans obsolete in JavaEE6 because of @Named in CDI/Weld? 【发布时间】:2011-02-25 05:32:22 【问题描述】:

由于 CDI(及其实现 Weld),JEE6 中的每个 POJO 都可以用 @Named 注释,这使得 POJO 可以访问视图。

这是否意味着 ManagedBeans 现在已经完全过时了? 还是我错过了 @ManagedBean 仍然有意义的东西?

【问题讨论】:

【参考方案1】:

简而言之,@ManagedBean 对于使用 JSF 但不使用 JSR 299(不管是什么原因)的应用程序是有意义的。下面是 Gavin King 的更长解释:

Re: Comparisons to @ManagedBean annotations in JSF2?:

查看 Weld 示例和较旧的 WebBean 文档,它看起来像 新的@ManagedBean JSF 的竞争对手 2.0 注释。有没有关于我们什么时候想使用的信息 一个比一个?

这是个好问题,但我不是 真的完全同意 到目前为止已经发布的答案。

新的 EE 托管 Bean 规范 定义了一个基本组件模型 Java EE,连同一个非常基础的 一组容器服务 (@Resource, @PostConstruct, @PreDestroy)。

这个想法是其他规格 (从 EJB、CDI、JSF 和 新的 Java 拦截器规范)建立在 这个基础组件模型和层 附加服务,例如 事务管理,类型安全 依赖注入,拦截器。所以 在这个级别,托管 bean、CDI、 拦截器和 EJB 规范 所有工作齐头并进,高度 互补。

现在,托管 Bean 规范 是相当开放的 准确识别哪些类是 托管豆。它确实提供了 @ManagedBean注解为一 机制,但它也允许其他 定义不同的规范 机制。所以,例如:

EJB 规范说,一个类服从特定的编程 @Stateless@Stateful 注释部署在一个 EJB jar 是一个托管 bean。

CDI 规范规定,任何具有适当构造函数的类 部署在“bean 部署 archive" 是一个托管 bean。

鉴于 EJB 和 CDI 提供 可以说是更方便的方法 识别托管 bean,您可能 想知道@ManagedBean 是什么 需要。答案,正如所提到的 丹,如果你有 CDI 在您的环境中可用(对于 例如,如果您使用的是 EE6),那么 @ManagedBean 不是真的 需要。 @ManagedBean 真的存在 供使用 JSF2 的人使用 没有 CDI

OTOH,如果你注释了一个 bean @ManagedBean,你确实有 CDI 你的环境,你仍然可以使用 CDI 将东西注入你的 bean。 只是@ManagedBean 注释在此不是必需 案例。

总而言之,如果您有 CDI 可供您使用,它提供了一个 优越的编程模型 @ManagedBean/@ManagedProperty型号 JSF2 继承自 JSF1。所以 事实上,EE 6 web 更优越 profile 不需要支持 @ManagedProperty 等。这个想法是 你应该改用 CDI。

【讨论】:

虽然问题中没有说明,但我阅读它是为了假设 JSR 299。【参考方案2】:

你有一个选择。使用 JSF2 中的 @ManagedBean 将 bean 绑定到表单中,或者使用 CDI 中的 @Named 注释。如果你只打算做 JSF,你可以坚持@ManagedBean,但是如果你想和 EJB 集成,或者使用 CDI 的 @ConversationScoped,那就走 CDI 路线。

我个人认为 JSF 的下一个版本应该弃用 @ManagedBean,并在 CDI 上标准化。这种二元性让新手感到困惑。

【讨论】:

【参考方案3】:

CDI 没有视图范围,因为它是doesn't have the notion of a view,所以如果你需要那个范围,纯粹形式的 CDI 是做不到的。查看范围基本上是指request scope + being AJAX-ready。它不是一个 JSF 视图,就像一个名为 xyz.xhtml 的页面,即使您看到 JSF <f:viewParam> 等。视图范围 bean 的一个常见用例是 how to get GET parameters into a such a bean。还有read this。

请注意,CDI 位于 EJB/服务层而不是 JSF/表示层。 This blog 有一个很好的概述。

因此,@ManagedBean 不能完全被 CDI 替换,如果您使用的是 @ViewScoped bean,至少不能不使用 extending CDI 或使用 Seam 3 Faces module。在使用基于 AJAXed JSF 2 的 GUI 工具包(如 RichFaces、PrimeFaces、IceFaces 等)时,几乎总是会使用视图范围的 bean。

混合来自错误 Java EE 6 包的注释可能给您带来意想不到的麻烦,再次使用 RichFaces 或类似 API 时:

@javax.faces.bean.ManagedBean
@javax.faces.bean.[Jsf]Scoped

用于表示层单独使用的组件,这里是 RichFaces、PrimeFaces 等。一些丰富的组件seem to have problems with CDI-annotated and JSF-annotated helper beans。如果您的 bean(或似乎什么都不做的 bean)出现奇怪的行为,则可能是错误的注释组合。

混合 JSF 和 CDI,比如

@javax.inject.Named
@javax.faces.bean.[Jsf]Scoped

在从 JSF 页面引用时在大多数情况下是可能的并且有效,但是有一些鲜为人知的问题/缺点,例如当using a JSF scope which CDI doesn't have:

此外,@Named @ViewScoped 组合也不会按预期工作。特定于 JSF 的 @ViewScoped 仅与特定于 JSF 的 @ManagedBean 结合使用。您的 CDI 特定的 @Named 将以这种方式表现得像 @RequestScoped。要么使用@ManagedBean 而不是@Named,要么使用CDI 特定的@ConversationScoped 而不是@ViewScoped

然后

@javax.inject.Named
@javax.faces.bean.[Cdi]Scoped

可用于直接从您的 JSF 页面 AFAIK 引用的 CDI bean。到目前为止,我对上述组合没有任何问题,因此您可以在此处考虑 @ManagedBean 已过时。

剩下的是服务层,这里主要是事务性 EJB 服务 bean 声明为

@javax.ejb.*

主要是@javax.ejb.Stateless。您甚至可以注释和使用EJBs directly from JSF pages - 尽管我不确定这种设计是否可取。引用(注入)任何带有 @javax.ejb.* 注释的组件,例如@Stateless,更喜欢@Inject 而不是@EJB as described here。 (可能是这个答案的祖先......)

最后,可以在这里找到 Java EE 6 注释的一个非常好的概述: http://www.physics.usyd.edu.au/~rennie/javaEEReferenceSheet.html

注意:以上信息并非来自专家,而只是我从新手的角度对这个可笑地令人困惑的 Java EE 6 注释意大利面条的看法/看法。更多的洞察力还有待开发。我希望这个答案能够成为对这种困惑的一般、实用的答案——即使它在原始问题的背景下有点过火了。

【讨论】:

您发布了一条回复评论,该评论还不错,但随后被一些力量接管,您将其更改为疯狂的 blob。人们建议 CDI 替代 @managed。问题很明确,但将苹果与橙子进行比较。 是的,有点。我仍然必须相信 CDI 是如何成为这样的替代品的。与此同时,新来者正在寻找解决方案,而不是“规范胡言乱语”。他们(我)需要一些帮助来决定在哪种情况下使用哪些注释来让事情顺利进行。恕我直言 我认为您已尽可能准确地回答了这个问题。事实上,我想要关于这个主题的 500 更多 字...... CDI 可以通过 CDI 扩展完美地利用 JSV @ViewScoped 注释。请参阅cwiki.apache.org/confluence/display/EXTCDI/JSF+Usage 只需使用 javax.faces.bean.ViewScoped 没有 ManagedBean 注解,CODI 将为您管理它(在 CDI 中)。 或缝合 3 个面。或任何等价物。【参考方案4】:

正如我刚刚阅读的Weld Reference(第 12 页),@ManagedBean 现在是多余的:

您可以显式声明一个托管 通过注解 bean 类 @ManagedBean,但在 CDI 中你没有 需要。根据 规范,CDI 容器 对待任何满足 以下条件作为托管 豆子:

它不是非静态内部类。它是一个具体的类,或者是 带注释的@Decorator。 未使用 EJB 组件定义注释进行注释或 声明为 EJB bean 类 ejb-jar.xml。 它没有实现 javax.enterprise.inject.spi.Extension。 它有一个合适的构造函数——要么: 该类有一个没有参数的构造函数,或者 该类声明了一个带有 @Inject 注释的构造函数。

【讨论】:

以上是关于由于 CDI/Weld 中的 @Named,@ManagedBeans 在 JavaEE6 中过时了吗?的主要内容,如果未能解决你的问题,请参考以下文章

Google Guice 与 JSR-299 CDI / Weld

使用 CDI/Weld 注入通用 Bean

线程“主”org.apache.spark.sql.AnalysisException 中的异常:由于数据类型不匹配,无法解析“named_struct()”:

如何从视图/内部代码访问 javax.faces.PROJECT_STAGE?

Apache service named reported the following error(OS 10055)由于系统缓冲区空间不足或队列已满解决办法?

No module named wsgi 求助