当前位置: 首页 > 知识库问答 >
问题:

Spring 4.1@JmsListener配置

许涵容
2023-03-14

我想为需要JMS侦听器的应用程序使用Spring 4.1中提供的新注释和功能。

我已经仔细阅读了Spring 4.1 JMS改进帖子中的注释,但我仍然错过了@JmsListenerDestinationResolver之间的关系,以及我将如何设置应用程序以指示正确的目标endpoint

以下是@JmsListener的建议使用

@Component
public class MyService {

    @JmsListener(containerFactory = "myContainerFactory", destination = "myQueue")
    public void processOrder(String data) { ... }
}

现在,我不能在我的实际代码中使用它,因为“myQueue”需要使用Environment.get属性()从配置文件中读取。

我可以使用DestinationResolver设置适当的myContainerFactory,但大多数情况下,如果您不需要JNDI在应用服务器中查找队列并且不需要执行一些自定义回复逻辑,您似乎只需使用DynamicDestinationResolver。我只是想了解Spring希望我如何使用@JmsListener注释以参数化方式指示队列的名称。

在博客文章的后面,我找到了对这个配置器的引用:

@Configuration
@EnableJms
public class AppConfig implements JmsListenerConfigurer {

@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
    registrar.setDefaultContainerFactory(defaultContainerFactory());

    SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
    endpoint.setDestination("anotherQueue");
    endpoint.setMessageListener(message -> {
        // processing
    });
    registrar.registerEndpoint(endpoint);
}

现在,这有一定的意义,我可以看到这允许我在运行时从一些外部字符串设置目的地,但这似乎与使用@JmsListener相冲突,因为它似乎覆盖了上面代码中有利于endpoint.setMessageListener的注释。

关于如何使用JmsListener指定适当的队列名称,有什么提示吗?

共有3个答案

葛宪
2023-03-14

您现在最终可以这样做,但这有点复杂。您可以使用JmsListenerConfigrer设置自定义JmsListenerEndpoint注册表

@Configuration
@EnableJms
public class AppConfig implements JmsListenerConfigurer {

    @Override
    public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
        registrar.setEndpointRegistry(customRegistry());
    }

}

然后重写registerListenerContainer方法,类似于

public void registerListenerContainer(JmsListenerEndpoint endpoint, JmsListenerContainerFactory<?> factory) {
    // resolve destination according to whatever -> resolvedDestination
    ((AbstractJmsListenerEndpoint)endpoint).setDestination(resolvedDestination);
    super.registerListenerContainer(endpoint, factory);
}

但我们可以做得更好。请观看/投票SPR-12280

党浩阔
2023-03-14

如果人们在spring boot中使用JmsListener,则不必配置PropertySourcesplaceConfigurer。它是现成的

样品:

@JmsListener(destination = "${spring.activemq.queue.name}")
    public void receiveEntityMessage(final TextMessage message) {
    // process stuff 
}
}

应用属性

spring.activemq.queue.name=some.weird.queue.name.that.does.not.exist

Spring防尘套输出

[26-Aug;15:07:53.475]-[INFO ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[931 ]-Successfully refreshed JMS Connection 
[26-Aug;15:07:58.589]-[WARN ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[880 ]-Setup of JMS message listener invoker failed for destination 'some.weird.queue.name.that.does.not.exist' - trying to recover. Cause: User user is not authorized to read from some.weird.queue.name.that.does.not.exist 
[26-Aug;15:07:59.787]-[INFO ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[931 ]-Successfully refreshed JMS Connection 
[26-Aug;15:08:04.881]-[WARN ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[880 ]-Setup of JMS message listener invoker failed for destination 'some.weird.queue.name.that.does.not.exist' - trying to recover. Cause: User user is not authorized to read from some.weird.queue.name.that.does.not.exist 

这证明了@JmsListener能够从application.properties中提取属性值,而无需实际设置任何显式的属性

我希望这有帮助!

晋弘义
2023-03-14

另请注意,根据用例,您已经可以使用每个环境和PropertySourcesplaceConfigurer的属性文件进行参数化

@JmsListener(destinations = "${some.key}")

按https://jira.spring.io/browse/SPR-12289

 类似资料:
  • 我有类,xml配置文件和错误堆栈跟踪像这样。我不知道为什么资格赛不起作用。我看到他甚至什么也没做。 狗 } 测试课程 } Springxml 错误堆栈跟踪 需要帮忙吗

  • Spring4.1实例化了Jackson实例。我有理由将该实例放入我的一个控制器中:该控制器使用Jackson进行一些小的JSON解析,但是它使用的应该是Spring本身使用的同一个实例。我该怎么做呢? 注意,我不是在问如何自定义配置Spring使用的;我对默认值很满意。我只想检索Spring out使用的实例,这样我就可以在自己的代码中重用现有的实例。

  • 在我的应用程序中,消息从一个队列移动到另一个队列,我想在日志中添加消息ID。我试图找出是否可以在实际处理之前拦截消息,并在MDC字段中设置消息ID,以便可以跨所有队列跟踪此消息。到目前为止,我还没有取得成功。是否存在任何现有解决方案?

  • 在这篇文章中,加里·拉塞尔解释了如何通过编程创建多个Kafka列斯汀来聆听多个主题。。Kafka·斯普林:如何动态或在循环中创建监听器? 现在我想有一个类似的设置也适用于JMSListeners-在那里我可以有一个带有一个@JMSListener的类,并且我可以以编程方式创建该JMSListener的多个实例,每个实例都注入了自己的queueName。 我发现这篇文章Spring JMS开始根据请

  • 我的代码中有一个Spring JmsListener。它接收和消费消息2天,但突然在这2天后,它没有收到来自外部Activemq的消息。然而,它的队列中有一些挂起的消息。当我重置Activemq和消费者时,消费者会收到大量消息。当消息挂起时,连接到Activemq的消费者(代表Spring致动器日志)。日志和配置显示Activemq没有将消息推送给消费者。我有另一个像这个消费者一样的服务从其他队列

  • 我正在开发一个服务,在该服务中,我侦听队列,反序列化接收到的消息,并将它们持久化到数据库(Oracle)。大致情况: 在缺省消息侦听器bean中,我设置并发性和setSessionTransactived(true)。这足以使整个onMessage具有事务性吗?因此,在一个事务中接收并保存一条消息,并在其中任何一点出现故障时回滚?当试图保存特定消息时,我尝试对其抛出异常,消息确实被回滚到队列,侦听