在 Spring 启动时即时修改 @JMSListener 目标
Modify @JMSListener destination on-the-fly on Spring Boot
我开发了一个 @JMSListener,它从 Java 属性获取目的地并且工作正常。
但现在我需要能够在运行时更改队列的 "destination" 而不必重置整个应用程序,即使我在运行时修改属性,队列 "destination" 不变。
这是我们实现@JMSListener 的方式:
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
@Component("b2b.CCRReceiver")
@Slf4j
public class CCRReceiver {
//SOME_VARIABLES
@Transactional
@JmsListener(destination = "${tibco.configuration.queues.upsert}", containerFactory = "jmsFactory", concurrency = "${jms.concurrency}")
public void receiveMessage(Message message) {
//DO_SOME_STUFF
}
}
如您所见,我第一次从值表达式中获取目标并且工作正常,但后来我不知道如何访问 JMSListener 并更改它的目标。
这能做到吗?有什么办法可以改变目的地吗?
或者我必须以允许我这样做的其他方式实现此 JMS 侦听器?
这应该有效:
给听众一个id
属性
自动连接 JmsListenerEndpointRegistry
(或以其他方式获取对它的引用)
registry.getListenerContainer("myListener").stop();
registry.getListenerContainer("myListener").shutdown();
((AbstractMessageListenerContainer) registry.getListenerContainer("myListener"))
.setDestinationName("newOne")
registry.getListenerContainer("myListener").initialize();
registry.getListenerContainer("myListener").start();
我使用组件侦听器线程解决了这个问题。使用TaskExecutor和ApplicationContext来管理。您可以在运行时创建。我还在努力。我也会尝试 Gary Russell 的建议。
对不起英语。欢迎指正。
applicationContext.getBean(ExampleListenerJMS.class);
...
taskExecutor.execute(exampleListenerJMS);
class 侦听器“实现 Runnable,MessageListener”,实现了自定义连接管理器(不同的 activemq 服务器)。
@Component
@Scope("application")
public class ExampleListenerJMS implements Runnable, MessageListener {
private EspecificManagerJMS jms = new EspecificManagerJMS();
@Override
public void run() {
customAndChekingActions();
}
protected void customAndChekingActions() {
...
try {
Destination destination = jms.getSession().createQueue(queue);
MessageConsumer consumer = jms.getSession().createConsumer(destination);
consumer.setMessageListener(this);
...
} catch (JMSException e) {
e.printStackTrace();
...
}
}
@Override
public void onMessage(Message message) {
...
}
希望对你有所帮助
我开发了一个 @JMSListener,它从 Java 属性获取目的地并且工作正常。
但现在我需要能够在运行时更改队列的 "destination" 而不必重置整个应用程序,即使我在运行时修改属性,队列 "destination" 不变。
这是我们实现@JMSListener 的方式:
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
@Component("b2b.CCRReceiver")
@Slf4j
public class CCRReceiver {
//SOME_VARIABLES
@Transactional
@JmsListener(destination = "${tibco.configuration.queues.upsert}", containerFactory = "jmsFactory", concurrency = "${jms.concurrency}")
public void receiveMessage(Message message) {
//DO_SOME_STUFF
}
}
如您所见,我第一次从值表达式中获取目标并且工作正常,但后来我不知道如何访问 JMSListener 并更改它的目标。
这能做到吗?有什么办法可以改变目的地吗?
或者我必须以允许我这样做的其他方式实现此 JMS 侦听器?
这应该有效:
给听众一个
id
属性自动连接
JmsListenerEndpointRegistry
(或以其他方式获取对它的引用)registry.getListenerContainer("myListener").stop();
registry.getListenerContainer("myListener").shutdown();
((AbstractMessageListenerContainer) registry.getListenerContainer("myListener"))
.setDestinationName("newOne")
registry.getListenerContainer("myListener").initialize();
registry.getListenerContainer("myListener").start();
我使用组件侦听器线程解决了这个问题。使用TaskExecutor和ApplicationContext来管理。您可以在运行时创建。我还在努力。我也会尝试 Gary Russell 的建议。 对不起英语。欢迎指正。
applicationContext.getBean(ExampleListenerJMS.class);
...
taskExecutor.execute(exampleListenerJMS);
class 侦听器“实现 Runnable,MessageListener”,实现了自定义连接管理器(不同的 activemq 服务器)。
@Component
@Scope("application")
public class ExampleListenerJMS implements Runnable, MessageListener {
private EspecificManagerJMS jms = new EspecificManagerJMS();
@Override
public void run() {
customAndChekingActions();
}
protected void customAndChekingActions() {
...
try {
Destination destination = jms.getSession().createQueue(queue);
MessageConsumer consumer = jms.getSession().createConsumer(destination);
consumer.setMessageListener(this);
...
} catch (JMSException e) {
e.printStackTrace();
...
}
}
@Override
public void onMessage(Message message) {
...
}
希望对你有所帮助