将 JSF 托管 bean 迁移到 CDI 托管 bean

Posted

技术标签:

【中文标题】将 JSF 托管 bean 迁移到 CDI 托管 bean【英文标题】:Migrate JSF managed beans to CDI managed beans 【发布时间】:2016-07-09 09:39:12 【问题描述】:

我计划将 Web 应用程序从使用 JSF 托管 bean 转换为使用 CDI 托管 bean。我知道我需要执行以下操作:

    在 WEB-INF 中添加一个空 beans.xml 文件。 将所有 JSF @ManagedBean 替换为 CDI @Named 注释。 用 CDI 或 OmniFaces 范围注释替换所有 JSF 范围注释。 将所有 JSF @ManagedProperty 替换为 CDI @Inject 注释。

这就是所有需要做的事情吗?有什么我需要注意的问题吗?

【问题讨论】:

答案取决于使用的服务器。例如在Tomcat 你也需要自己安装 CDI。 我正在使用 TOMEE。因此,CDI 已经可用。我更担心 webapp 中的问题。很难测试应用程序的各个方面。所以,如果有已知的陷阱,很高兴知道要提防。 【参考方案1】:

基本上,只要您已经在 J​​ava EE 服务器上,这确实是您需要做的所有事情。在 Tomcat 上,您需要先手动安装 CDI。 Weld 和 OpenWebBeans 的说明详见博客 How to install CDI in Tomcat?

需要注意以下问题:

虽然 OmniFaces 2.x “官方”需要 JSF 2.2,但 OmniFaces 2.0/2.1 在技术上与 JSF 2.1 向后兼容,并且在 TomEE 的案例中也应该在 TomEE 1.x 上与 JSF 2.1 兼容,但 OmniFaces 2.2 具有一个硬 JSF 2.2 依赖项(由于新的 <o:viewAction> 标签)并且不会在 TomEE 1.x 上部署,除非将其 MyFaces JSF 实现升级到 2.2 兼容版本,或者本身升级到 TomEE 7.x。另见OmniFaces Compatibility Matrix。

当您部署具有多个 WAR 且每个 WAR 具有自己的 OmniFaces 库的 EAR 时,通常所有 CDI 功能将仅在一个 WAR 中工作,因为 WAR 提供的库的 CDI 上下文被错误地解释为 EAR 范围。这是 CDI 规范中的一个疏忽,尚未在未来的 CDI 版本中修复。另见OmniFaces Known Issues (CDI)。

1234563一个或一个空的),那么您需要确保在beans.xml 中明确设置了bean-discovery-mode="all"。另见@FacesConverter showcase。

当替换 @ManagedBean(eager=true) 时,请注意标准 CDI 对此没有直接等效项。您将为此使用@Observes。 OmniFaces 为此提供了@Eager 注释。另见How to configure a start up managed bean?

在 JSF 2.0/2.1/2.2 中替换 @ManagedProperty 时,请注意您不能单独通过 @Inject 直接注入 #param.xxx#cookie.xxx#initParam.xxx,虽然这是可能的通过@ManagedProperty。 OmniFaces为此分别提供@Param@Cookie@ContextParam。只有在 JSF 2.3 中有一个新的 @javax.faces.annotation.ManagedProperty 注释,其使用方式与自 JSF 2.3 以来已弃用的原始 @javax.faces.bean.ManagedProperty 完全相同。

【讨论】:

感谢 BalusC。我做了 1 - 4,并做了一些测试,一切似乎都在工作。惊讶地如此无缝。旁注:我最近将此应用程序从 Websphere 8.1 (myfaces2.0) 迁移到 TOMEE 1.7 (myfaces 2.1.17)。从那时起,我们一直遇到内存问题。 TOMEE 服务器在运行一周后挂起,原因是最大堆。我注意到内存转储中有很多 viewscoped bean。我希望omnifaces 的viewscoped 可以帮助消除这个问题。我只是不明白为什么 Websphere 中没有发生问题。哦,好的,谢谢指点。

以上是关于将 JSF 托管 bean 迁移到 CDI 托管 bean的主要内容,如果未能解决你的问题,请参考以下文章

JSF-2.3 找不到我的 @Named CDI-1.2 托管 bean

使用 CDI(上下文和依赖注入)支持 bean 而不是托管 Bean

JSF 2.x @ViewScoped 托管 bean 线程安全吗?

GlassFish 域中的 JSF 托管 Bean 唯一性

Field.get(obj) 在注入的 CDI 托管 bean 上返回所有空值,同时手动调用 getter 返回正确的值

迁移到 tomcat 后,将枚举值作为参数从 JSF 页面传递给 bean 方法失败