如何让 Spring 连接我的 JmsComponent

2024-04-18

我正在编写一个使用 Akka、Akka-Camel 和 Spring 进行配置的应用程序。应用程序需要充当针对各种应用程序服务器的独立 JMS 客户端,为此,它需要使用 JNDI 设置 JMS 连接工厂。我正在用 jBoss 测试这个。我对jBoss 5和6也有同样的问题(这似乎是客户端Spring问题,与jBoss无关)。

我正在使用以下 xml 配置 Spring beans:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:camel="http://camel.apache.org/schema/spring"
       xmlns:jee="http://www.springframework.org/schema/jee"
       xsi:schemaLocation="
         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
         http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
         http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
         ">

    <camelContext id="camel" trace="false" xmlns="http://camel.apache.org/schema/spring">
        <jmxAgent id="agent" disabled="true"/>
    </camelContext>

    <jee:jndi-lookup id="jmsConnectionFactory" jndi-name="ConnectionFactory">
        <jee:environment>
            java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
            java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
            java.naming.provider.url=jnp://192.168.0.109:1099
        </jee:environment>
    </jee:jndi-lookup>

    <bean name="jms" class="org.apache.camel.component.jms.JmsComponent">
        <property name="connectionFactory" ref="jmsConnectionFactory" />
    </bean>

</beans>

正如你所看到的,我正在设置:

  • 通过 JNDI 初始化的 ConnectionFactory,称为 jmsConnectionFactory
  • 一个 JmsComponent,其 connectionFactory 属性设置为前一个 bean

使用此配置,我的应用程序在启动时失败:

java.lang.IllegalArgumentException: connectionFactory must be specified
    at org.apache.camel.util.ObjectHelper.notNull(ObjectHelper.java:294) ~[camel-core.jar:2.10.4]
    at org.apache.camel.component.jms.JmsConfiguration.createConnectionFactory(JmsConfiguration.java:1053) ~[camel-jms.jar:2.10.4]
    at org.apache.camel.component.jms.JmsConfiguration.getConnectionFactory(JmsConfiguration.java:416) ~[camel-jms.jar:2.10.4]
    at org.apache.camel.component.jms.JmsConfiguration.createListenerConnectionFactory(JmsConfiguration.java:1062) ~[camel-jms.jar:2.10.4]
    at org.apache.camel.component.jms.JmsConfiguration.getListenerConnectionFactory(JmsConfiguration.java:435) ~[camel-jms.jar:2.10.4]
    at org.apache.camel.component.jms.JmsConfiguration.configureMessageListenerContainer(JmsConfiguration.java:889) ~[camel-jms.jar:2.10.4]
    at org.apache.camel.component.jms.JmsConfiguration.createMessageListenerContainer(JmsConfiguration.java:379) ~[camel-jms.jar:2.10.4]

这来自 JmsConfiguration.java 中的这段代码:

protected ConnectionFactory createConnectionFactory() {
    ObjectHelper.notNull(connectionFactory, "connectionFactory");
    return null;
}

因此,Spring bean 初始化似乎无法按照此处的说明关联/连接 bean(从之前粘贴的完整 XML Spring 配置中提取):

    <bean name="jms" class="org.apache.camel.component.jms.JmsComponent">
        <property name="connectionFactory" ref="jmsConnectionFactory" />
    </bean>

我还尝试创建一个中间 JmsConfiguration bean,并设置 JmsComponent 的配置属性,而不是直接设置 connectionFactory 属性,但我在两种设置中得到相同的结果。

顺便说一句,我可以通过代码连接 bean。我的意思是:

val connFactory = springContext.getBean[javax.jms.ConnectionFactory]("jmsConnectionFactory", classOf[javax.jms.ConnectionFactory])
camelContext.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connFactory))

工作得很好。所以我知道我正在从 JNDI 获取 ConnectionFactory,只是我无法使用正确的 Spring 配置来将其连接到 XML 中。

我需要这个应用程序具有很强的可配置性,而无需重新编译,因此让 XML 正常工作对我来说是必须的。

如果还不清楚,问题是:如何让 Spring 设置我的 JmsComponent bean,并将其 connectionFactory 设置为 JNDI 获取的工厂?

编辑:使用 Camel 的要点是它应该允许我将该组件交换为另一个不同类型的组件。所以今天我使用 JMS,也许明天我将使用 TCP。这就是为什么能够在 XML 中定义所有内容非常重要。


我相信问题在于 Akka 使用它自己的 CamelContext 而不是 Spring 配置中定义的。在 Akka 的早期版本中,这似乎是可能的设置 Akka 使用的上下文 http://doc.akka.io/docs/akka-modules/1.3.1/modules/camel.html#Standalone_Spring_applications,但在最新版本中似乎不再可能。

我遇到了同样的问题,我在 Java(而不是 Scala)中使用基于注释的配置,并使用以下代码解决了该问题:

@Bean
public ActorSystem getCamelActorSystem(ConnectionFactory factory) {

    ActorSystem system = ActorSystem.create("some-system");

    Camel camel = CamelExtension.get(system);
    CamelContext camelContext = camel.context();
    camelContext.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(factory));

    return system;
}

这会注入在其他地方定义的 ConnectionFactory 依赖项,并使用它将 jms 组件添加到 Akka 使用的camelContext。

另一个解决方案可能是以某种方式扩展 CamelExtension 代码,以允许注入camelContext 依赖项,就像以前可能的那样。然而,我假设他们有充分的理由进行改变,所以我就不管它了。我认为这样他们就可以确保上下文不能更改,因此 Actor 系统始终使用相同的 Camel 上下文,这是基于以下内容:

对于每个 ActorSystem,一个 CamelExtension 只加载一次, 这使得您可以在您的任何时候安全地调用 CamelExtension 代码来获取与其关联的 Apache Camel 对象。有 每个 ActorSystem 对应一个 CamelContext 和一个 ProducerTemplate 使用 CamelExtension。

http://doc.akka.io/docs/akka/current/scala/camel.html#CamelExtension http://doc.akka.io/docs/akka/current/scala/camel.html#CamelExtension

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

如何让 Spring 连接我的 JmsComponent 的相关文章

随机推荐

  • SoapExtension 未加载

    我正在尝试写一个肥皂扩展 但框架没有加载它 我已经添加到 web config
  • 不同的Android SDK版本使用不同的图标

    我的 Android 菜单有图标 在 Android 3 上 我使用黑色 ActionBar 因此图标为白色 然而 在 Android 2 x 上 菜单本质上是白色的 这意味着图标几乎不可见 如何为不同版本使用不同的菜单图标 我假设我可以使
  • 我们如何重命名MySQL 5.0中的数据库名称[重复]

    这个问题在这里已经有答案了 我在用MySQL 5 0 我创建了一个名为accounts 但现在我想将数据库名称更改为FinanceAccounts 如何更改数据库名称MySQL 5 0 我认为只有一种方法 除了重命名 MySQL datad
  • 安全移动 Microsoft SDK 文件夹

    我的硬盘上有一个文件夹 C Program Files Microsoft SDKs 我想知道将其移动到外部驱动器是否安全 Visual Studio 或任何其他工具是否依赖于此特定文件夹 注册表中有相当多的条目 至少在我的注册表中 指向该
  • Cython指定固定长度字符串的numpy数组

    我有一个函数 我想使用 Cython 来处理大量固定长度的字符串 对于标准 cython 函数 我可以像这样声明数组的类型 cpdef double g double in arr cdef double out arr np zeros
  • 对话框的对象位置 Libgdx

    我有一个对话框 Dialog dialog new Dialog style dialog setSize 400 500 dialog setPosition Gdx graphics getWidth 2 200 Gdx graphic
  • 使用自动 bash 脚本检查 FTP 中是否存在文件

    我想自动化执行以下操作的批处理作业 检查我的file txt存在于FTP服务器中 我将其重命名为file trt 检查我的file txt and file trt存在 如果存在我发送电子邮件 我运行另一个脚本 最后我删除file trt
  • Ruby+Anemone Web Crawler:正则表达式匹配以一系列数字结尾的 URL

    假设我正在尝试抓取一个网站并跳过一个像这样结束的页面 我目前正在 Ruby 中使用 Anemone gem 来构建爬虫 我正在使用skip links like方法 但我的模式似乎永远不匹配 我试图使其尽可能通用 因此它不依赖于子页面 而只
  • 为什么这个 Sql 语句(有 2 个表连接)需要 5 分钟才能完成?

    更新 下面添加了 3 个更新 以下sql语句需要5分钟才能完成 我只是 不 得到 它 第一个表有 6861534 行 第二个表少了一点 第三个表 包含 4 个地理字段 与第一个表相同 Those GEOGRAPHY第三个表中的字段 它们不应
  • 错误域=FIRFirestoreErrorDomain 代码=7“权限缺失或不足。”

    所以我有以下代码从 firestore 检索文档 该函数在我的 viewDidLoad 中调用 func loadAnnotations db collection jumpSpotAnnotations getDocuments quer
  • 将静态库链接到共享库

    我正在尝试在 Ubuntu Linux 上使用 g 5 4 0 创建共享库 我已经构建了 Poco C 库的静态库 a 文件 我想将它们静态链接到我的共享库中 但它不起作用 我已将以下字符串添加到我的构建脚本中 Wl whole archi
  • 如何使用c#读取EPS的属性或颜色信息?

    我的要求是读取另外50个EPS文件并导出EPS的属性 颜色模式 这可能吗 颜色模式有灰度 RGB 和 CMYK 到目前为止 我尝试使用 BitmapImage 来读取 EPS 但我没有运气 BitmapImage 不读取 EPS 因为它是矢
  • ANDROID:如何将视频文件下载到 SD 卡?

    我在网站上有一个 MP4 格式的视频文件 我希望用户能够通过单击链接将该视频下载到他们的 SD 卡上 是否有捷径可寻 我目前有这段代码 但它不起作用 不知道我做错了什么 谢谢你的帮助 import java io BufferedInput
  • Titan 加载弹性搜索问题

    我使用以下代码来加载泰坦 TitanFactory Builder config TitanFactory build config set storage backend berkeleyje config set storage dir
  • 指针的大小以及该大小是否取决于体系结构

    好吧 抱歉这个问题 更像是一个一般文化问题 尚未找到准确的答案 如果我有类似的东西 char Field or void Field or double pointers 指针的大小是一样的吗 据我记得大学时它是 4 个字节 但是 根据CP
  • 类型错误 - Python 中的类

    我是 Python 的初学者 刚刚开始掌握课程 我确信这可能是非常基本的东西 但为什么这段代码是这样的 class Television def init self print Welcome your TV self volume 10
  • 多个函数聚合的结果不可用于进一步计算。为什么?

    我对 R 中聚合函数的结果有疑问 我的目标是从数据集中选择某些鸟类并计算密度 调查区域内观察到的个体的数量 为此 我获取了主数据文件的子集 然后在区域上进行聚合 计算 平均值和个体数量 由向量长度表示 然后我想用计算出的平均面积和个体数量来
  • 异或数据包中的所有数据

    我需要一个可以根据用户输入计算校验和的小程序 不幸的是 我对校验和的了解只是它是数据包中所有数据的异或 我试图在网上搜索一个例子 但没有运气 我知道我是否有一个字符串 41 4D 02 41 21 04 02 02 00 00 00 00
  • 如何在 Android 上的 Camera2 API 中设置“CONTROL_AE_EXPOSURE_COMPENSATION”?

    我目前正在开发 Androids Camera 2 API 当前的问题是我无法设置 CONTROL AE EXPOSURE COMPENSATION 我的代码 1 0 public void setExposure double expos
  • 如何让 Spring 连接我的 JmsComponent

    我正在编写一个使用 Akka Akka Camel 和 Spring 进行配置的应用程序 应用程序需要充当针对各种应用程序服务器的独立 JMS 客户端 为此 它需要使用 JNDI 设置 JMS 连接工厂 我正在用 jBoss 测试这个 我对