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

2024-02-23

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

目前我正在使用 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,但这些教程都没有展示如何将实体分散到不同的包中(模块的模型项目)。例如,我想要三个不同的模块

  • Core
  • User
  • Blog

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

如何使 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


为了回答您的一些问题,使用单个持久性单元,但将您的实体分布在多个捆绑包中不推荐,但偶尔可能会起作用 http://mail-archives.apache.org/mod_mbox/aries-user/201009.mbox/%3CBLU128-W23FF762B1355954B4AFA4DF7D0@phx.gbl%3E。但是,如果您的实体关系如此密切,以至于它们需要共享一个持久性单元,那么将它们拆分到模块中可能没有意义。另外,不要忘记您可以通过分离每个实体的实现和接口来处理编译时依赖关系 - 接口和实现不必位于同一个包中。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 OSGi 和 EE6 模块化企业应用程序? 的相关文章

随机推荐

  • 如何从 Mercurial 存储库中安全地禁用/删除大型文件目录?

    过去 我一直在 Mercurial 中使用大型文件扩展来将数据与我正在处理的代码一起保存 我认为这是一个错误 我想删除 largefiles 目录 8GB 我们的网络用户目录限制为 10 GB 我需要空间 我已经很长时间没有使用任何大文件了
  • Spark Yarn模式如何从spark-submit获取applicationId

    当我使用带有主纱线和部署模式集群的spark submit提交spark作业时 它不会打印 返回任何applicationId 并且一旦作业完成 我必须手动检查MapReduce jobHistory或spark HistoryServer
  • 就地对字典进行排序

    如何就地对字典进行排序 它没有像这样的排序方法list sort d 3 three 1 one 2 two tmp dict sorted d items d clear d update tmp 想要这样的结果 但应该就地正确 即不使用
  • 无法在 MySQL 中插入度数符号

    当我插入度数符号而不是保存它时 使用 PHP 输入表单 因为它在 MySQL 中显示的值是 例如如果我写 37 C 它被保存为 37 C 这是我的代码的示例
  • 使用视频脚本作为 div 背景 [ HTML / CSS ] [重复]

    这个问题在这里已经有答案了 抱歉 如果我的曲子不好听 我有这段html代码 HTML div class video bg Some Code to execute div CSS video bg width 600px height 6
  • 如何在 Tornado 中从子进程向 websocket-client 发送消息?

    我有龙卷风服务器 它从 websocket 连接接收消息 我需要将工作人员功能作为单独的进程运行 并且工作人员应该回答客户端 主要思想是在并行模式下工作 像这样的东西 def worker ws message input json loa
  • WASAPI:以最小延迟播放正弦波声音,无毛刺(独占事件驱动模式)

    我尝试在独占模式下使用 Windows 音频会话 API WASAPI 播放简单的正弦波形 但无论我做什么 都会遇到声音故障 我一直在使用MSDN 独占模式流示例 https msdn microsoft com en us library
  • Android:java.lang.IllegalArgumentException:服务未注册

    我有活动 启动服务并绑定它 但我希望即使活动关闭我的服务也能运行 所以我需要取消绑定它 当我尝试这样做 调用我的函数disconnectFromService 时 我总是遇到此异常 服务绑定成功 可以正常通信了 仅当服务已绑定时 我才尝试解
  • 使用 Google Sheets/Google Drive API 请求特定文件权限

    我正在使用 Google Sheets API 获取 Java 项目的工作表数据 一切都在本地按预期工作 但我使用的是详细权限范围https www googleapis com auth spreadsheets https www go
  • 常量表达式中具有未初始化成员的“默认”构造函数

    以下最小示例因未初始化数组数据成员而被 Clang 和 GCC 拒绝 class vector3 public constexpr vector3 default private float m data 3 constexpr auto
  • 带有超链接的 Pandas read_excel

    我有一个 Excel 电子表格 正在将其读入 Pandas DataFrame df pd read excel file xls 但是 电子表格的其中一列包含具有与其关联的超链接的文本 如何访问 Pandas 中的底层超链接 这可以用 o
  • 自定义 UITableViewCell 内的水平 UIScrollView - 使用 IB Storyboard - 不滚动

    主要目标是能够水平滚动每行的内容 我正在尝试使用 X Code 5 和 StoryBoard 来做到这一点 问题似乎很简单 但是经过几个小时的搜索 除了一个有点相似但仅使用编程方法的问题之外 我什么也没得到 see here https s
  • Android 动画时删除视图错误

    private void kartyafeleanim String idx1 String idx2 Animation anim1 AnimationUtils loadAnimation mycontext R anim scalab
  • Oracle数据库:如何选择所有列但首先返回某些列?

    背景 我有一个 Oracle 数据库表 其中有很多列 我正在对这些列运行一些查询 我不知道我在查询中到底要查找什么数据 所以我想返回所有列 但我不想寻找和啄食我知道有意义的列 Question 假设有一个表 表 1 A 列 B 列 C 列
  • 将菜单按钮添加到 VS2010 TFS 查询结果或工作项栏中

    我正在尝试将按钮添加到 Visual Studio TFS2010 工作项查询结果菜单栏以及为各个工作项显示的菜单栏 见下图 这实际上是可定制的且可行的吗 如果可以 如何实现 我会看一下这篇文章 TFS 2010 将菜单项添加到构建资源管理
  • 从浏览器检测Windows 10

    我需要在客户端运行 Windows 10 S 特别是 S 仅 Win 10 还不够 时将浏览器重定向到特定页面 用户代理似乎没有指定这一点 我已经找到了在客户端上通过 C 和 WMI 获取此数据的解决方案 但我需要在网页上运行 Javasc
  • MvvmLight EventToCommand 和 WPFToolkit DataGrid 双击

    试图弄清楚如何使用 EventToCommand 为行设置数据网格双击处理程序 该命令位于每行的视图模型中 只是that很大程度上来自我的经验 因为我还没有使用过交互 Thanks 我本来会使用 mvvmlight 标签 但我还没有足够高的
  • 如何使用 Kotlin DSL 创建 Fat JAR?

    我正在使用 Gradle 5 5 我有一个基于 Groovy 的构建脚本 我正在尝试将其迁移到 Kotlin DSL 这jar任务包含将所有依赖项复制到 JAR 文件的典型行 from configurations compile coll
  • 打开键盘时隐藏页脚 ionic4

    参考了这个链接 在键盘打开 Ionic3 上隐藏页脚 https stackoverflow com questions 48386422 hide footer on keyboard open ionic3 但问题也是一样的 问题与上图
  • 如何使用 OSGi 和 EE6 模块化企业应用程序?

    我知道已经有一些与该主题相关的问题 但我还找不到真正的解决方案 目前我正在使用 EE6 JPA CDI JSF 开发应用程序 我想采用一种更加模块化的方法 而不是将所有内容打包到 WAR 或 EAR 中并将整个内容部署在应用程序服务器上 我