【问题标题】:How to modularize an Enterprise Application with OSGi and EE6?如何使用 OSGi 和 EE6 模块化企业应用程序?
【发布时间】:2012-07-02 07:48:32
【问题描述】:

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

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

我正在尝试通过将一个模块分成 3 个 maven 项目来将我的应用程序设计为尽可能模块化:

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

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

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

JPA

让我们先看看 JPA。周围有一些教程[1] 解释了如何制作启用 JPA 的 OSGi Bundle,但这些教程都没有展示如何将实体分散到不同的 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] 应该能以某种方式解决这个问题,但我不熟悉它。

我想在模块“core”中有一个项目“CoreWeb”,它包含一个 Facelet 模板,我们称之为“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

【问题讨论】:

    标签: jsf jpa osgi java-ee-6 cdi


    【解决方案1】:

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

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

    【讨论】:

    • 核心模块还包含对可用实体的通用访问,因此我必须只有一个 PU,但如果我不必将它们打包到一个 jar 文件中就更好了。可能有一些 maven 插件会进行打包,但 IMO 它在某种程度上不太像 OSGi。我已经研究了一些蓝图示例,但我不喜欢 xml 配置的非类型安全性。如果没有其他选择,那么我可能不得不使用它或自己实施 CDI 解决方案。
    • Christian,你有没有为你的模块化应用找到完美的解决方案。你能和我分享一下吗?我也有同样的问题?
    • 我找不到任何直接的解决方案。我有点在等待 Java 9(Jigsaw)和使用这些模块的 EE 版本。 JPA 项目的当前解决方案:使用一个包含子模块的 orm.xml 文件的持久性项目。 CDI 项目的当前解决方案:将项目保持原样分开,并在添加依赖项时小心。 Web 项目的当前解决方案:如果可能,将内容分离到子项目中,并在构建中组合所有内容。如果要添加新模块或将所有模块放入应用程序但只显示子集,请重新部署。
    猜你喜欢
    • 2018-09-28
    • 2011-04-28
    • 2012-04-30
    • 2012-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多