由于 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
线程“主”org.apache.spark.sql.AnalysisException 中的异常:由于数据类型不匹配,无法解析“named_struct()”:
如何从视图/内部代码访问 javax.faces.PROJECT_STAGE?
Apache service named reported the following error(OS 10055)由于系统缓冲区空间不足或队列已满解决办法?