Ceci est une question distincte mais liée à mon article précédent ici: Terminer en toute sécurité une application Spring JMS
Mon application JMS que j'utilise avec Spring Boot traite tout correctement et s'arrête sans erreur. Pour que cela fonctionne, j'ai changé un bean de:
@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;
}
Le problème avec ceci est que j'aurais pu créer juste un "hotfix", car mes connaissances sur le printemps sont limitées. la ligne dans le bean modifié a jmsListenerContainer.setAutoStartup(false);
été ajoutée lorsque je suis tombé sur ce post: http://forum.spring.io/forum/spring-projects/integration/79176-illegalstateexception-no-message-listener-specified comme sans le autoStartup
set à false Je reçois ceci après chaque message traité dans mes journaux:
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]
Tout est toujours traité et arrêté correctement, je le vois simplement dans mes journaux. Je ne sais pas s'il y a un conflit dans mon fichier de configuration ou non qui peut en être la racine. Je veux juste m'assurer que les modifications ne causeront pas de problèmes, même si tout fonctionne actuellement comme prévu sans erreur.
Enfin, voici toute ma classe de configuration:
@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);
}
}
Pensées? Est-ce compliqué?
EDIT: Écouteur 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 {...}
Je suis confus.
DefaultJmsListenerContainerFactory
est à utiliser avec les méthodes POJO annotées:
@JmsListener(...)
public void foo(String bar) {...}
La fabrique est utilisée pour créer le conteneur d'écouteur de la méthode.
Avec votre configuration de remplacement, je ne vous vois jamais configurer un écouteur de message dans le DefaultMessageListenerContainer
.
Habituellement, vous auriez container.setMessageListner(myListener)
où myListener
est un MessageListener
, un SessionAwareMessageListener
ou un MessageListenerAdapter
qui enveloppe un auditeur POJO.
Définir autoStartup
sur false et ne jamais démarrer le conteneur ne fait rien sauf ajouter le bean conteneur au contexte.
Je ne vois pas comment vous pouvez jamais obtenir des messages avec cette configuration.
ÉDITER
Utilisez-vous Spring Boot? Si tel est le cas, cela créera une valeur jmsListenerContainerFactory
par défaut pour vous - c'est ma meilleure estimation.
Dans ce cas, votre code d'arrêt n'arrête pas vraiment le conteneur réel - juste le "factice" qui n'a jamais été démarré.
Je vous suggère de donner votre @JmsListener
an id
, @Autowire
le JmsListenerEndpointRegistry
et appeler registry.getListenerContainer("myListener").stop()
.
@JmsListener(id = "myListener", destination = "${mq.queueName}")
Cet article est collecté sur Internet, veuillez indiquer la source lors de la réimpression.
En cas d'infraction, veuillez [email protected] Supprimer.
laisse moi dire quelques mots