我知道已经有一些与该主题相关的问题,但我还找不到真正的解决方案。
目前我正在使用 EE6、JPA、CDI、JSF 开发应用程序。我想采用一种更加模块化的方法,而不是将所有内容打包到 WAR 或 EAR 中并将整个内容部署在应用程序服务器上。
我试图通过将模块分成 3 个 Maven 项目来尽可能模块化地设计我的应用程序:
- API - 包含(无状态)服务的接口
- 模型 - 包含特定模块的 JPA 实体
- Impl - 包含 API 的实现,主要是 CDI bean
每个模块的视图逻辑目前都捆绑在一个大型 Web 项目中,这很丑陋。我已经考虑过 Web 片段,但如果我将 bean 类和 xhtml 文件分散在 jar 文件中,我将必须实现一个钩子,以便父 Web 应用程序可以查找资源。这种解决方案至少使我能够为每个模块创建第四个项目,其中包含与该模块相关的所有视图逻辑,这是一个良好的开始。
我想要的不仅是我可以拥有这4种项目,而且每个项目都是热插拔的。这让我想到了 OSGi,一开始它真的很酷,直到我意识到 EE6 技术在 OSGi 容器中并没有得到很好的支持。
JPA
我们先看一下JPA。有一些教程 [1] 解释了如何制作支持 JPA 的 OSGi Bundle,但这些教程都没有展示如何将实体分散到不同的包中(模块的模型项目)。例如,我想要三个不同的模块
博客模块的模型项目对用户的模型项目具有(编译时)依赖性。
用户模块的模型项目对核心的模型项目具有(编译时)依赖性。
如何使 JPA 在这种情况下工作,而无需为模块的每个模型项目创建持久性单元?我想要一个持久性单元能够了解运行时可用的所有实体。实体所在的模型项目当然应该是可热插拔的。也许我需要为每个客户端创建一个单独的项目,导入项目所需的所有实体,并包含一个包含所有必要配置内容的 persistence.xml。是否有任何可用的 Maven 插件用于构建此类项目,甚至有其他方法来解决该问题?
CDI
CDI 非常好。我真的很喜欢它,我不想再错过它了!我使用 CDI 扩展,例如 MyFaces CODI 和 DeltaSpike,它们非常棒!
我将我的(无状态)服务注入其他服务或视图层,这非常棒。由于我的服务是无状态的,因此将它们用作 OSGi 服务应该不成问题,但是 OSGi 中的 CDI 集成怎么样?我发现了 glassfish CDI 扩展 [2],它将 OSGi 服务注入到 CDI bean 中,但我也希望可能的 OSGi 服务成为 CDI bean。我不完全确定如何实现这一点,可能我必须使用 BeanManager 实例化实现,然后在 BundleActivator 中的 ServiceRegistry 中注册其接口的每个实现。有没有标准的方法可以做到这一点?我想避免对 OSGi 框架的任何(编译时)依赖性。
我还想像现在使用它们一样使用我的服务,而不做任何更改(未注释的实现和不合格的注入点)。
有一个 JBoss Weld 扩展/子项目 [3] 似乎针对该问题,但它似乎不活跃,我找不到任何最佳实践或操作方法。
如何让我的实现保持原样但仍然能够使用 OSGi?我的意思是,向实现添加注释并不是什么大问题,因为每个实现都已经用构造型注释进行了注释,无论如何我想防止这种情况发生。
JSF
正如之前提到的,我希望能够明智地扩展我的视图逻辑模块。据我所知,这实际上不可能开箱即用。 Pax Web[4] 应该以某种方式解决这个问题,但我对此并不熟悉。
我想在模块“core”中有一个项目“CoreWeb”,其中包含 Facelet 模板,我们将其称为“template.xhtml”。然后,模块“blog”中名为“BlogWeb”的项目中的 JSF 页面应该能够引用该模板并应用组合。
为了能够扩展视图,我将引入一个 java 接口“Extension”,它可以由模块的特定类实现。然后,视图的控制器将注入扩展的所有实现。例如,扩展将提供将包含在主视图中的子视图列表。
所描述的扩展机制可以很容易地实现,但必须满足以下要求:
- 当向应用程序服务器添加新的 OSGi Bundle 时,可用扩展集可能会发生变化,这些扩展必须可用于视图的控制器。
- 应包含在主视图中的子视图(来自单独的包)应该是可访问的。
Spring Slices[5] 的单主机多切片应用的概念非常有趣,但似乎仅限于 Spring DM Server,并且该项目似乎也不活跃。
Summary
在我描述了所有示例和行为之后,我希望您知道我想要实现的目标。它只是一个非常动态和模块化的 EE6 应用程序。
我最后寻找的至少是关于如何让一切按照我的预期运行的文档,甚至更好的是一个已经有效的解决方案!
[1] http://jaxenter.com/tutorial-using-jpa-in-an-osgi-environment-36661.html http://jaxenter.com/tutorial-using-jpa-in-an-osgi-environment-36661.html
[2] https://blogs.oracle.com/sivakumart/entry/typesafe_injection_of_dynamic_osgi https://blogs.oracle.com/sivakumart/entry/typesafe_injection_of_dynamic_osgi
[3] http://www.slideshare.net/TrevorReznik/weldosgi-injecting-easiness-in-osgi http://www.slideshare.net/TrevorReznik/weldosgi-injecting-easiness-in-osgi
[4] http://team.ops4j.org/wiki//display/paxweb/Pax+Web http://team.ops4j.org/wiki//display/paxweb/Pax+Web
[5] https://jira.springsource.org/browse/SLICE https://jira.springsource.org/browse/SLICE