6

我知道已经有一些与该主题相关的问题,但我还没有找到真正的解决方案。

目前我正在使用 JPA、CDI、JSF 使用 EE6 开发应用程序。我想采用一种更模块化的方法,而不是将所有东西都打包到 WAR 或 EAR 中,然后将整个东西部署在 Application Server 上。

我试图通过将一个模块分成3个maven项目来尽可能地设计我的应用程序:

  • API - 包含(无状态)服务的接口
  • 模型 - 包含特定模块的 JPA 实体
  • Impl - 包含 API 的实现,主要是 CDI bean

每个模块的视图逻辑目前都捆绑在一个大型 Web 项目中,这很丑陋。我已经想到了 web 片段,但是如果我在 jar 文件中传播我的 bean 类和 xhtml 文件,我将不得不实现一个挂钩,以便父 web 应用程序可以查找资源。这种解决方案至少使我能够为每个模块创建第四个项目,该项目将包含与模块相关的所有视图逻辑,这是一个好的开始。

我想要的不仅是我可以拥有这四种项目,而且每个项目都是可热插拔的。这让我想到了 OSGi,起初它真的很酷,直到我意识到 EE6 技术在 OSGi 容器中并没有得到很好的支持。

JPA

让我们先看看 JPA。有一些教程 [1] 解释了如何制作启用 JPA 的 OSGi Bundle,但这些教程都没有展示如何将实体分散到不同的包中(模块的模型项目)。例如,我想要三个不同的模块

  • 用户
  • 博客

博客模块的模型项目对用户的模型项目有(编译时)依赖。用户模块的模型项目对核心的模型项目有(编译时)依赖。

如何让 JPA 在这种情况下工作,而不必为模块的每个模型项目创建持久性单元?我想要一个知道运行时所有可用实体的持久性单元。实体所在的模型项目当然应该是可热插拔的。也许我需要为每个客户端创建一个单独的项目,该项目导入所有需要的项目实体并包含一个包含所有必要配置内容的 persistence.xml。是否有任何可用的 maven 插件来构建这样的项目,甚至有其他方法来解决这个问题?

CDI

CDI 非常好。我真的很喜欢它,我不想再错过它了!我使用 CDI 扩展,例如 MyFaces CODI 和 DeltaSpike,它们很棒!我将我的(无状态)服务注入到其他服务或视图层中,这非常棒。由于我的服务是无状态的,因此将它们用作 OSGi 服务应该没有问题,但是 OSGi 中的 CDI 集成呢?我发现了一个 glassfish CDI Extension[2],它可以将 OSGi 服务注入 CDI bean,但我也希望 OSGi 服务可以是 CDI bean。我不完全确定如何实现这一点,可能我必须使用 BeanManager 来实例化实现,然后在 BundleActivator 中的 ServiceRegistry 中为其接口注册每个实现。有没有这样做的标准方法?我想避免对 OSGi 框架的任何(编译时)依赖。

我也想像现在使用我的服务一样使用我的服务,而不做任何更改(未注释的实现和未限定的注入点)。有一个 JBoss Weld 扩展/子项目 [3] 似乎针对该问题,但它似乎处于非活动状态,我找不到任何最佳实践或操作方法。我怎样才能让我的实现保持原样但仍然能够使用 OSGi?我的意思是向实现添加注释并不是什么大不了的事,因为每个实现都已经用原型注释进行了注释,无论如何我想防止这种情况发生。

JSF

如前所述,我希望能够明智地传播我的视图逻辑模块。据我所知,这并不是开箱即用的。Pax Web[4] 应该以某种方式解决这个问题,但我不熟悉它。

我想在包含 Facelet 模板的模块“core”中有一个项目“CoreWeb”,我们称之为“template.xhtml”。然后,模块“blog”中名为“BlogWeb”的项目中的 JSF 页面应该能够引用该模板并应用组合。

为了能够扩展视图,我将引入一个可以由模块的特定类实现的 java 接口“扩展”。然后,视图的控制器将注入扩展的所有实现。例如,扩展将提供将包含在主视图中的子视图列表。

所描述的扩展机制可以很容易地实现,但必须满足以下要求:

  • 将新的 OSGi Bundle 添加到应用程序服务器时,可用扩展集可能会更改,这些扩展必须可用于视图的控制器。
  • 应该包含在主视图中的子视图(来自单独的包)应该是可访问的。

Spring Slices[5] 的单宿主多切片应用的概念非常有趣,但似乎仅限于 Spring DM Server,并且该项目似乎也处于非活动状态。

概括

在我描述的所有示例和行为之后,我希望你知道我想要实现什么。它只是一个非常动态和模块化的 EE6 应用程序。

我最终寻找的至少是关于如何让所有东西按照我的预期运行的文档,或者甚至更好的已经工作的解决方案!

[1] http://jaxenter.com/tutorial-using-jpa-in-an-osgi-environment-36661.html

[2] https://blogs.oracle.com/sivakumart/entry/typesafe_injection_of_dynamic_osgi

[3] http://www.slideshare.net/TrevorReznik/weldosgi-injecting-easiness-in-osgi

[4] http://team.ops4j.org/wiki//display/paxweb/Pax+Web

[5] https://jira.springsource.org/browse/SLICE

4

1 回答 1

1

要回答您的一些问题,不建议使用单个持久性单元但将实体分散到多个捆绑包中,但有时可能会起作用。但是,如果您的实体如此密切相关以至于它们需要共享一个持久性单元,那么将它们跨模块拆分可能没有意义。此外,不要忘记您可以通过分离每个实体的实现和接口来处理编译时依赖关系——接口和实现不必在同一个包中。

对于依赖注入,您可能喜欢 Blueprint。有多种实现可用,并且大多数具有企业 OSGi 支持的应用程序服务器都支持开箱即用的蓝图。它使用 XML 添加元数据,因此类本身不需要任何修改。

于 2012-07-03T07:07:34.350 回答