JSF、CDI 和 EJB 容器:应该使用它们的哪种组合?
Posted
技术标签:
【中文标题】JSF、CDI 和 EJB 容器:应该使用它们的哪种组合?【英文标题】:JSF, CDI and EJB containers : which combination of them should be used? 【发布时间】:2013-10-20 09:56:08 【问题描述】:我正在阅读this post,这让我有些困惑:在那篇文章中提到了每个特定容器使用哪个注释:JSF、CDI 或 EJB 容器。
作为一个初学者,我学习了 JSF 框架,并习惯了它的 @ManagedBean 注释及其用于从 JSF 页面引用 bean 的可选名称参数,并且对 CDI 了解不多,而我使用 EJB 来代替它的强大功能(即使在阅读了这篇文章后,我仍然认为 EJB 比 CDI 更强大、更有特色)。
所以.. JSF 和 CDI 容器都有自己的注释和在网页上引用 bean 的方式,但 EJB 只有 @Stateless(或 @Stateful),因此不能在网页上引用,这意味着JSF 容器必须始终附有 EJB(因为我认为混合 EJB 和 CDI 容器是荒谬的,因为它们几乎相似,但在这一点上,我希望有人告诉我我是否错了)。
JSF 容器的问题在于它是
“还没有完全成熟的容器”
正如那篇帖子所说,我所知道的最糟糕的是 Netbeans 中 @ManagedBean 旁边的警告消息:
"javax.faces.bean 包中的注解将被弃用 下一个 JSF 版本。建议使用 CDI。"
(好吧,这里还有另一个用于该注释的替代包:javax.annotation.ManagedBean,但我不知道我是否可以使用它,也不知道它是否具有用于在网页上引用 bean 的参数以及哪个是的)
所以现在我开始思考未来我应该使用哪种容器组合。 CDI + EJB 是未来吗?
为所有人喝彩。
【问题讨论】:
【参考方案1】:Java EE 7 越来越与 CDI 保持一致。因此,EJB 将只是 CDI + 强大服务(异步、消息消费者、调度任务......)的一个非常特殊的案例。考虑到这一点,@ManagedBean
变得多余,因为@Named
允许您将 bean 公开给 JSF 页面。
随着技术的成熟,CDI 容器无处不在(即使对于独立应用程序也是如此)。
需要记住的几点:
服务层不仅适用于@Stateless
或@Stateful
。现在,每个类都可以是@Named
并被注入(并使用这意味着作为拦截器、生命周期管理、资源注入的服务)。
演示文稿不仅适用于@ManagedBean
。每个@Named
都可能位于具有相关范围(会话、视图...)的网页后面
不仅 EJB 是事务性的,现在每个 @Named
和 @Transactional
(Java EE 7) 都可以写入数据库。
架构得到简化,模式相同(MVC,边界控制实体),只需更改注释和一点点实现即可。
目前有一个名为 Apache DeltaSpike 的成熟项目,其中包含一些可移植的相关 CDI 扩展,并且在大多数情况下会简化您的生活(即使您使用的是 Java EE 6!)。
注意:在 Java EE 7 中使用完整的 CDI 可能比在 Java EE 6 中更容易,因为 6 没有 @Transactional
,所以你需要自己创建一个事务拦截器。
DeltaSpike 说:
对非 EJB bean 的事务支持:事务拦截器 DeltaSpike 为 Java EE 7 中的 @Transactional 铺平了道路。
【讨论】:
【参考方案2】:首先,我想区分 EJB 和 JSF 托管 Bean。 EJB 是持久对象,作为一般规则,您不能将它们直接用作 JSF 托管对象,因为 JSF 对象管理子系统不允许数据库的需要。最重要的是,交换具有不同键的对象的实例。您的所有数据库操作都需要应用程序代码,因为 JSF 无法帮助您。它不是为此而设计的。
对于传统管理与 CDI:除非 Oracle 做一个“微软”并放弃对已弃用项目的传统长期支持,否则使用旧式 ManagedBean 注解应该更安全。而且,事实上,根据您所针对的 Enterprise Java 容器的版本,CDI 可能还不能正常工作。
如果您确定您将始终获得 CDI 支持,那么编写 CDI 代码可能会更好,因为它是专门用于长期支持的。
【讨论】:
以上是关于JSF、CDI 和 EJB 容器:应该使用它们的哪种组合?的主要内容,如果未能解决你的问题,请参考以下文章
JSF-2.3 找不到我的 @Named CDI-1.2 托管 bean