在 WildFly 上将 JPA 和 CDI Beans 与 Camel 结合使用

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 63w+ 字,讲解图 2808+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2200+ 小伙伴加入学习 ,欢迎点击围观

我并没有真正为此计划,但是有了一个月的免费会议,我有机会深入挖掘并向您展示更多 WildFly-Camel 子系统提供的 Camel on WildFly 魔法。

业务背景

该演示源自 Christina Lin 在 JBoss Demo-Central 上的一个演示。她演示了 Camel 中 File 和 JDBC 连接器的使用,并添加了 Spilled 模式和异常处理方法的使用。 demo的场景是模拟银行账户之间的交易流程。输入是一个包含大量交易的批处理 XML 文件。这些可以是现金存款,现金提取或银行账户的转账信息。根据交易的类型,它们被溢出,每笔交易从数据库中检索相关信息,进行交易并计算交易费用,然后再将它们放回数据库中。您可以 在 GitHub 上找到完整的原始源代码

为什么我碰它

一些原因:我实际上不想考虑新的业务案例。并且不只是想在技术层面上向您展示一些细节。所以,我认为从 Christina 那里获取场景是一个快速的胜利。其次,她在基于 Karaf 的 Fuse 中完成所有工作,并使用 XML DSL 进行路由定义。我只是一个可怜的 Java 人,学会了讨厌 XML。另外,她使用了几个组件,而我不会在 Java EE 上下文中使用这些组件。

先决条件 - 部署应用程序

在开始试用演示之前,请确保已 安装 WildFly 8.2.0.Final 以及 WildFly-Camel 子系统补丁 2.2.0 。现在可以随意将 我的 github 帐户上的演示存储库 分叉到您选择的目录中。它只不过是一个带有一些附加依赖项的 maven Java EE 7 项目。做一个


 mvn clean install

并将生成的 target/javaee-bankdemo-1.0-SNAPSHOT.war 部署到您的 WildFly 服务器。

此示例中没有任何 UI,因此您基本上必须查看日志文件并复制一个 xml 文件。 src\main\in-data 文件夹包含一个 bank.xml,您需要将其复制到您的 standalone\data\inbox 文件夹。第二次完成后,骆驼开始施展魔法。

客户状态

一切都从标准的 Java EE 应用程序开始。实体 CustomerStatus 保存帐户信息(ID、VipStatus、余额)。它也有一些 NamedQueries。看起来根本不是骆驼特有的。 WildFly 用作默认数据库的内存中 H2 数据库在三个脚本的帮助下预先填充,这些脚本在 persistance.xml 中配置为模式生成属性。我在这里与两个客户一起工作,分别名为 A01 和 A02。

骆驼和 Java EE

在这种情况下,Camel 引导非常简单。 BankRouteBuilder 有一个 @ContextName("cdi-context") 注释,它本身是一个应用程序范围的启动 bean,它包含小演示所需的所有路由。请随意重新阅读并了解 部署/配置路由的其他潜在选项 。 hawt.io 控制台 (http://localhost:8080/hawtio/) 很好地显示了所有这些内容。该应用程序有五个路由。

ReadFile 是第一个,它基本上只准备 xml 文件并将各个条目( 由 xPath 表达式拆分 )推送到 processTransaction 路由。

这决定了它是“现金”交易还是“转账”交易。分别以“ direct:doTransfer ”或“ direct:processCash ”结尾。我将 BankRouteBilder 中的所有原始 xml 路由定义保留为注释。如果您搜索特定的解决方案,可能会有帮助。

与保险丝演示的差异

Christina 经常使用 Camel JDBC 组件 。它完成所有繁重的工作,甚至 初始数据库 设置。这不是我们想在任何地方做的事情,尤其是在我们准备好使用所有 JPA 魔法的 Java EE 环境中。事实上,有一个 Camel JPA componente ,但它非常有限,并不真正支持 NamedQueries 或类似的东西。

一个非常强大的解决方法是使用 Camel Bean 组件 和所有 bean 绑定以及已经集成的 cdi 组件。所有数据库访问都通过 CustomerStatusService 进行管理。这基本上是一个 @Named bean,它被注入了一个 EntityManager 并且知道如何加载 CustomerStatus 实体。通过简单地在 bean 端点中引用它,它被注入到 RouteBuilder 中:


 mvn clean install

我同意,在幕后发生了很多魔法,事实上,CustomerStatusService 依赖于 Camel 类是另一回事,我不喜欢。但这可以很容易地解决,只需将服务 @Inject-ing 到路由中并类似地引用它。我决定不这样做,因为我想保持 Christina 演示的初始流程。她经常与交易所合作并依赖它们。所以,我更接近她的榜样。

关于交易的一句话

我实际上在这个例子中使用了一个扩展的持久上下文,并将 服务中的 updateCustomer 方法标记为 @Transactional 。这是将完整和更新的 CustomerStatus 实体合并回数据库的一种非常简单的方法。整个 doTransfer 路线现在不是事务性的。即使第二个客户不在系统中,该金额仍会从第一个客户帐户中提取。我想在稍后阶段和单独的博客文章中介绍这一点。

就这样吧。享受你的周末,玩玩 Camel 和 WildFly Camel 子系统。很高兴通过 @myfear 收到您的想法或问题,或作为对博客文章的评论。

相关文章