如何使用OSGi和EE6模块化企业应用程序?

时间:2012-07-01 18:13:12

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

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

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

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

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

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

我想要的不仅仅是我可以拥有这4种项目,而且每个项目都是热插拔的。这让我想到了OSGi,在我意识到EEG技术在OSGi容器中得不到很好的支持之前,它起初非常酷。

JPA

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

  • 核心
  • 用户
  • 博客

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

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

CDI

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

我也想像我现在一样使用我的服务,而不改变任何东西(没有注释的实现和不合格的注入点)。 有一个JBoss Weld扩展/子项目[3]似乎针对这个问题,但似乎是不活跃的,我找不到任何最佳实践或方法。 如何保留我的实现,但仍然可以使用OSGi?我的意思是在实现中添加注释并不是什么大问题,因为每个实现都已经使用构造型注释进行了注释,无论如何我想要阻止它。

JSF

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

我想要一个项目" CoreWeb"在模块"核心"它包含一个Facelet模板,我们称之为" template.xhtml"。一个名为" BlogWeb"的项目中的JSF页面。在模块"博客"然后应该能够引用该模板并应用合成。

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

所描述的扩展机制可以轻松实现,但必须满足以下要求:

  • 将新的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

1 个答案:

答案 0 :(得分:1)

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

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