繁体   English   中英

尝试使用 Spring 引导使用 JMS 主题消息时出现异常

[英]Exception while trying to consume a JMS Topic message using Spring Boot

我正在尝试使用来自 ActiveMQ 主题的消息。 以下是代码:

@Configuration
@EnableJms
public class Config {

@Value("${activemq.broker-url}")
private String brokerURL;

@Bean
public ActiveMQConnectionFactory activeMQConnectionFactory() {
    ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
    activeMQConnectionFactory.setBrokerURL(brokerURL);
    activeMQConnectionFactory.setTrustAllPackages(true);
    return activeMQConnectionFactory;
}

public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(){
    DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory = new DefaultJmsListenerContainerFactory();
    defaultJmsListenerContainerFactory.setConnectionFactory(activeMQConnectionFactory());
    defaultJmsListenerContainerFactory.setPubSubDomain(true);
    return defaultJmsListenerContainerFactory;
}

我的消费者代码:

@Component
@EnableJms
public class Consumer {

   @JmsListener(destination = "xml.inbound.topic", containerFactory = "jmsListenerContainerFactory")
   public void Processor(final Message xmlMessage) {

   }
}

我得到的例外是:

通过字段 'jmsTemplate' 表达的不满足的依赖关系; 嵌套异常是 org.springframework.beans.factory.BeanCreationException:在 class 路径资源 [com/investmentbank/equityfeedsprocessingrevised/config/Config.class] 中定义名称为“jmsTemplate”的 bean 创建错误:通过工厂方法进行 Bean 实例化失败; 嵌套异常是 org.springframework.beans.BeanInstantiationException:无法实例化 [org.springframework.jms.core.JmsTemplate]:工厂方法“jmsTemplate”抛出异常; nested exception is java.lang.ClassCastException: class org.springframework.jms.config.DefaultJmsListenerContainerFactory cannot be cast to class javax.jms.ConnectionFactory (org.springframework.jms.config.DefaultJmsListenerContainerFactory and javax.jms.ConnectionFactory are in unnamed module of加载程序“应用程序”)

我在这里做错了什么? 为什么例外?

我也试过:

@Bean
public DefaultMessageListenerContainer jmsListenerContainerFactory() {
        DefaultMessageListenerContainer dmlc = new DefaultMessageListenerContainer();
        dmlc.setConnectionFactory(activeMQConnectionFactory());
        dmlc.setPubSubDomain(true);
        return dmlc;
}

我在这里得到的例外是:

通过字段 'jmsTemplate' 表达的不满足的依赖关系; 嵌套异常是 org.springframework.beans.factory.BeanCreationException:在 class 路径资源 [com/investmentbank/equityfeedsprocessingrevised/config/Config.class] 中定义名称为“jmsTemplate”的 bean 创建错误:通过工厂方法进行 Bean 实例化失败; 嵌套异常是 org.springframework.beans.BeanInstantiationException:无法实例化 [org.springframework.jms.core.JmsTemplate]:工厂方法“jmsTemplate”抛出异常; 嵌套异常是 org.springframework.beans.factory.BeanCreationException:在 class 路径资源 [com/investmentbank/equityfeedsprocessingrevised/config/Config.class] 中定义名称为“jmsListenerContainerFactory”的 bean 创建错误:调用 init 方法失败; 嵌套异常是 java.lang.IllegalArgumentException:需要属性“destination”或“destinationName”

只是添加我的 JmsTemplate 代码如下所示:

@Bean
public JmsTemplate jmsTemplate() {
JmsTemplate jmsTemplate = new JmsTemplate();
         jmsTemplate.setConnectionFactory(activeMQConnectionFactory());
         jmsTemplate.setPubSubDomain(true);
         return jmsTemplate;
}

我已经使用 Apache Camel(代码)实现了 JMS 主题发布器:

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
        CamelContext _ctx = new DefaultCamelContext(); 
        _ctx.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory));
        _ctx.addRoutes(new RouteBuilder() {

            public void configure() throws Exception {
                from("file:src/main/resources?fileName=data-sample_2.csv")
                .process(new MyTransformRevised1())
                .to("file:src/main/resources/?fileName=emp.xml")                
                .split(body().tokenizeXML("equityFeeds", null)).streaming().to("jms:topic:xml.inbound.topic");
            }

        });

我可以在我的主题名称的“消息入队”列中看到消息的数量。

出了什么问题? 我在网上阅读了各种帖子,但无法解决问题。 请帮助解决问题。 我无法阅读有关 ActiveMQ 主题的消息。 让我知道我是否缺少某些信息。

您可以尝试将CachingConnectionFactory包装在activeMQConnectionFactory中并利用DefaultJmsListenerContainerFactoryConfigurer来配置JmsListenerContainerFactory

@Bean
ConnectionFactory connectionFactory() {
    return new CachingConnectionFactory(activeMQConnectionFactory());
}

@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerFactory(ConnectionFactory connectionFactory,
                                    DefaultJmsListenerContainerFactoryConfigurer configurer) {

    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    configurer.configure(factory, connectionFactory);
    return factory;
}

编辑开始:

您可以尝试将JmsTemplate更改为:

@Bean
public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
JmsTemplate jmsTemplate = new JmsTemplate();
         jmsTemplate.setConnectionFactory(connectionFactory);
         jmsTemplate.setPubSubDomain(true);
         return jmsTemplate;
}

我用下面的代码解决了这个问题:

    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(){
    DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory = new DefaultJmsListenerContainerFactory();
                defaultJmsListenerContainerFactory.setConnectionFactory(activeMQConnectionFactory());
defaultJmsListenerContainerFactory.setPubSubDomain(true);
return defaultJmsListenerContainerFactory;
        }

     @Bean
     public JmsTemplate jmsTemplate() {
        JmsTemplate jmsTemplate = new JmsTemplate();
        jmsTemplate.setConnectionFactory(activeMQConnectionFactory());
        jmsTemplate.setPubSubDomain(true);
        return jmsTemplate;
    }

    @JmsListener(destination = "${my.inboundTopicName}", containerFactory = "jmsListenerContainerFactory")
    public void myProcessor(final Message xmlMessage) {
    ///

    }

我想补充一点,我遇到了一些不寻常的行为。

  1. 在从生产者生成消息时,如果消费者启动,则只有消息被消费者消费。 我的意思是,如果消息由生产者生成并由 ActiveMQ 排队,并且在一段时间后我打开消费者,则消息不会被消费者消费。

  2. . 消息被消费者消费之前也需要一段时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM