gpt4 book ai didi

java - JMS 配置类中可能出现的奇怪行为

转载 作者:行者123 更新时间:2023-12-01 09:57:04 25 4
gpt4 key购买 nike

这是一个与我之前的帖子相关的单独问题:Safely Terminating a Spring JMS application

我使用 Spring Boot 的 JMS 应用程序可以正确处理所有内容并正常关闭。为了让它工作,我改变了一个bean:

@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
factory.setConnectionFactory(mqConnectionFactory());
factory.setDestinationResolver(destinationResolver());
factory.setConcurrency("1");
factory.setErrorHandler(errorHandler());
factory.setSessionTransacted(true);
factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
return factory;
}

致:

@Bean
public DefaultMessageListenerContainer defaultMessageListenerContainer() {
DefaultMessageListenerContainer jmsListenerContainer = new DefaultMessageListenerContainer();
jmsListenerContainer.setConnectionFactory(mqConnectionFactory());
jmsListenerContainer.setDestinationResolver(destinationResolver());
jmsListenerContainer.setDestinationName(queueName);
jmsListenerContainer.setConcurrency("1");
jmsListenerContainer.setErrorHandler(errorHandler());
jmsListenerContainer.setSessionTransacted(true);
jmsListenerContainer.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
jmsListenerContainer.setAutoStartup(false);
return jmsListenerContainer;
}

问题是,我本可以只创建一个“修补程序”,因为我对 spring 的了解很少。当我偶然发现这篇文章时,添加了更改后的 bean jmsListenerContainer.setAutoStartup(false); 中的行: http://forum.spring.io/forum/spring-projects/integration/79176-illegalstateexception-no-message-listener-specified如果没有将 autoStartup 设置为 false,我会在日志中处理每条消息后收到此消息:

java.lang.IllegalStateException: No message listener specified - see property 'messageListener'
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:691) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:651) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:315) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:253) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1150) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1142) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:1039) [spring-jms-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at java.lang.Thread.run(Unknown Source) [?:1.8.0_74]

一切仍然被正确处理和关闭,我只是在日志中看到这一点。不确定我的配置文件中是否存在冲突,这可能是问题的根源。我只是想确保更改不会导致问题,即使目前一切都按预期运行且没有错误。

最后这是我的整个配置类:

@Configuration
@EnableJms
public class MQConfig {

private static final Logger logger = LogManager.getLogger(MQConfig.class.getName());

@Value("${mq.hostName}")
String host;
@Value("${mq.port}")
Integer port;
@Value("${mq.queueManager}")
String queueManager;
@Value("${mq.queueName}")
String queueName;
@Value("${mq.channel}")
String channel;

@Autowired
Environment environment;

@Bean
public DefaultMessageListenerContainer defaultMessageListenerContainer() {
DefaultMessageListenerContainer jmsListenerContainer = new DefaultMessageListenerContainer();
jmsListenerContainer.setConnectionFactory(mqConnectionFactory());
jmsListenerContainer.setDestinationResolver(destinationResolver());
jmsListenerContainer.setDestinationName(queueName);
jmsListenerContainer.setConcurrency("1");
jmsListenerContainer.setErrorHandler(errorHandler());
jmsListenerContainer.setSessionTransacted(true);
jmsListenerContainer.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
jmsListenerContainer.setAutoStartup(false);
return jmsListenerContainer;
}

@Bean
public MQConnectionFactory mqConnectionFactory() {
MQConnectionFactory mqConnectionFactory = new MQConnectionFactory();

try {
mqConnectionFactory.setHostName(host);
mqConnectionFactory.setPort(port);
mqConnectionFactory.setQueueManager(queueManager);
mqConnectionFactory.setTransportType(1);
} catch (JMSException ex) {
logger.error(ex.getStackTrace());
}

return mqConnectionFactory;
}

@Bean
public DynamicDestinationResolver destinationResolver() {
DynamicDestinationResolver destinationResolver = new DynamicDestinationResolver();

try {
Connection connection = mqConnectionFactory().createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
destinationResolver.resolveDestinationName(session, queueName, false);
} catch (JMSException ex) {
logger.error(ex.getStackTrace());
}

return destinationResolver;
}

@Bean
public MQQueue mqQueue() {
MQQueue mqQueue = new MQQueue();

try {
mqQueue.setBaseQueueName(queueName);
mqQueue.setBaseQueueManagerName(queueManager);
} catch (JMSException ex) {
logger.error(ex.getStackTrace());
}

return mqQueue;
}

@Bean
public JmsErrorHandler errorHandler(){
return new JmsErrorHandler();
}

@Bean
public MQManager mqHoldManager(){
return new MQManager(host, port, queueName,
queueManager, channel);
}

@Bean
public MQInitializer mqInitializer(){
return new MQInitializer(environment);
}


}

想法?这很乱吗?

编辑:JMS 监听器

@Component
public class MQConsumer {

@Resource(name = "mqHoldManager")
private MQManager mqHoldManager;
@Resource(name = "defaultMessageListenerContainer")
private DefaultMessageListenerContainer listenerContainer;

@Autowired
MQInitializer mqInitializer; /* To ensure this bean executes before Listener Setup not necessarily for any particular usage*/

final Logger logger = LogManager.getLogger(MQConsumer.class.getName());
private static ReportManager reportManager = new ReportManager();
private static boolean isFirstQueue = true;

@JmsListener(destination = "${mq.queueName}")
public void processOrder(String message) throws Exception {...}

最佳答案

我很困惑。

DefaultJmsListenerContainerFactory 用于带注释的 POJO 方法:

@JmsListener(...)
public void foo(String bar) {...}

工厂用于为方法创建监听器容器。

通过您的替换配置,我没有看到您将消息监听器配置到 DefaultMessageListenerContainer 中。

通常你会有container.setMessageListner(myListener),其中myListener是一个MessageListener、一个SessionAwareMessageListener或包装 POJO 监听器的 MessageListenerAdapter

autoStartup 设置为 false 并且从不启动容器除了将容器 bean 添加到上下文之外不会执行任何操作。

我不明白你如何能够通过该配置获取任何消息。

编辑

你使用Spring Boot吗?如果是这样,它将为您创建一个默认的jmsListenerContainerFactory - 这是我最好的猜测。

在这种情况下,您的停止代码并没有真正停止实际容器 - 只是从未启动的“虚拟”容器。

我建议你给你的@JmsListener一个id@AutowireJmsListenerEndpointRegistry并调用 registry.getListenerContainer("myListener").stop().

@JmsListener(id = "myListener", destination = "${mq.queueName}")

关于java - JMS 配置类中可能出现的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37118640/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com