Как прослушивать 3 разные очереди tibco ems с помощью Spring (циклическая зависимость)

#spring-jms #circular-reference #message-listener

Вопрос:

У нас есть приложение, которое подключается к 3 различным очередям tibco, размещенным на одном сервере ems. Мы используем websphere 8.5 с java 8. Я создал провайдера tibco и мои фабрики соединений на сервере, предоставив также пользователя и пароль. У нас есть 3 потребителя:потребитель tibcomessaging, потребитель tibcotimercon и потребитель tibcocrm. Все 3 расширяют универсальный потребитель класса, реализующий элемент списка сообщений.

Если у меня есть только один из слушателей, все идет нормально, я аутентифицируюсь в очереди с помощью пользователя и передаю данные, и я могу читать сообщения и работать с ними. С другой стороны, если у меня есть 3 слушателя, я получаю ошибку круговой ссылки

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messagingModuleListener': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'crmModuleListener': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'timerModuleListener': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'CrmTibcoRemoteConnectionFactory': Requested bean is currently in creation: Is there an unresolvable circular reference?  at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:311) ~[spring-context-4.2.0.RELEASE.jar:4.2.0.RELEASE]  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) [spring-beans-4.2.0.RELEASE.jar:4.2.0.RELEASE]  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) [spring-beans-4.2.0.RELEASE.jar:4.2.0.RELEASE]  at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) [spring-beans-4.2.0.RELEASE.jar:4.2.0.RELEASE]  

ниже приведена часть моего кода:

 ////imports here  @Component("messagingModuleListener") public class TibcoMessagingConsumer extends GenericConsumer {    @Resource(lookup = "jms/QueueConnectionFactory")  private ConnectionFactory connFactory;    @Resource(lookup= "jms/MESSAGING.Q.v1")  private Queue queue;   @Override  public synchronized void onMessageLogic(MessageConsumedEventDto consumedEventMsg) {  //// do stuff   }   @Bean(name = "TibcoRemoteConnectionFactory")  public ConnectionFactory getTopicConn() {    Context ctx=null;  try {  ctx = new InitialContext ();  connFactory= (QueueConnectionFactory)ctx.lookup("jms/QueueConnectionFactory");  } catch (NamingException e) {  e.printStackTrace();  }  return connFactory;  }   @Bean(name = "TibcoRemoteQueue")  public Queue getTopic() {  Context ctx=null;   try {  ctx = new InitialContext ();  queue= (Queue)ctx.lookup("jms/MESSAGING.Q.v1");  } catch (NamingException e) {  e.printStackTrace();  }  return queue;  } }   ///////  //imports  @Component("timerModuleListener") public class TibcoTimerConsumer extends GenericConsumer {   @Resource(lookup = "jms/TmrQueueConnectionFactory")  private ConnectionFactory connFactory;    @Resource(lookup= "jms/TIMER.Q.v1")  private Queue tmrqueue;   @Override  public void onMessageLogic(MessageConsumedEventDto consumedEventMsg) {   //do stuff  }   @Bean(name = "TimerTibcoRemoteConnectionFactory")  public ConnectionFactory getTopicConn() {  try {  Context ctx = new InitialContext();  connFactory = (QueueConnectionFactory) ctx.lookup("jms/TmrQueueConnectionFactory");  } catch (NamingException e) {  e.printStackTrace();  }  return connFactory;  }   @Bean(name = "TimerTibcoRemoteQueue")  public Queue getTopic() {  Context ctx = null;  try {  ctx = new InitialContext();  tmrqueue = (Queue) ctx.lookup("jms/TIMER.Q.v1");  } catch (NamingException e) {  e.printStackTrace();  }  return tmrqueue;  } }  

контекст xml выглядит следующим образом:

 lt;?xml version="1.0" encoding="UTF-8"?gt;   lt;beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:aop="http://www.springframework.org/schema/aop"  xmlns:context="http://www.springframework.org/schema/context"  xmlns:util="http://www.springframework.org/schema/util" xmlns:jee="http://www.springframework.org/schema/jee"  xmlns:c="http://www.springframework.org/schema/c" xmlns:task="http://www.springframework.org/schema/task"  xmlns:tx="http://www.springframework.org/schema/tx"  xmlns:jms="http://www.springframework.org/schema/jms"  xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd   http://www.springframework.org/schema/aop   http://www.springframework.org/schema/aop/spring-aop.xsd   http://www.springframework.org/schema/context   http://www.springframework.org/schema/context/spring-context.xsd   http://www.springframework.org/schema/util   http://www.springframework.org/schema/util/spring-util.xsd   http://www.springframework.org/schema/jee   http://www.springframework.org/schema/jee/spring-jee.xsd  http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  http://www.springframework.org/schema/task  http://www.springframework.org/schema/task/spring-task-3.0.xsd  http://www.springframework.org/schema/jms  http://www.springframework.org/schema/jms/spring-jms.xsd"gt;   lt;context:component-scan base-package="eu.unicredit.xframe.chx" scoped-proxy="targetClass"  use-default-filters="false"gt;  lt;context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/gt;  lt;context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/gt;  lt;context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/gt;  lt;/context:component-scangt;   lt;context:spring-configured/gt;  lt;context:annotation-config/gt;  lt;task:annotation-driven/gt;      lt;bean id="transactionManager" class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/gt;  lt;tx:annotation-driven/gt;   lt;bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"gt;  lt;property name="dataSource" ref="dataSource"/gt;  lt;/beangt;   lt;bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"gt;  lt;constructor-arg ref="dataSource"/gt;  lt;/beangt;   lt;bean id="lobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler"gt;  lt;property name="nativeJdbcExtractor" ref="nativeJdbcExtractor"/gt;  lt;/beangt;   lt;bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.WebSphereNativeJdbcExtractor"/gt;   lt;bean class="eu.unicredit.xframe.chx.commons.utils.SpringUtils"/gt;   lt;bean id="tibcoDataListener" class="org.springframework.jms.listener.DefaultMessageListenerContainer"  depends-on="transactionManager, TibcoRemoteConnectionFactory, TibcoRemoteQueue, messagingModuleListener" gt;  lt;property name="connectionFactory" ref="TibcoRemoteConnectionFactory"/gt;  lt;property name="destination" ref="TibcoRemoteQueue"/gt;  lt;property name="messageListener" ref="messagingModuleListener"/gt;  lt;property name="sessionTransacted" value="true"/gt;  lt;property name="transactionManager" ref="transactionManager"/gt;  lt;property name="maxConcurrentConsumers" value="5"/gt;  lt;property name="concurrentConsumers" value="1"/gt;    lt;/beangt;  lt;!-- lt;bean id="tibcoDataListenerCrm" class="org.springframework.jms.listener.DefaultMessageListenerContainer" --gt; lt;!-- depends-on="transactionManager, CrmTibcoRemoteConnectionFactory, CrmTibcoRemoteQueue, crmModuleListener"gt; --gt; lt;!-- lt;property name="connectionFactory" ref="CrmTibcoRemoteConnectionFactory"/gt; --gt; lt;!-- lt;property name="destination" ref="CrmTibcoRemoteQueue"/gt; --gt; lt;!-- lt;property name="messageListener" ref="crmModuleListener"/gt; --gt; lt;!-- lt;property name="sessionTransacted" value="true"/gt; --gt; lt;!-- lt;property name="transactionManager" ref="transactionManager"/gt; --gt; lt;!-- lt;property name="maxConcurrentConsumers" value="5"/gt; --gt; lt;!-- lt;property name="concurrentConsumers" value="1"/gt; --gt; lt;!-- lt;/beangt; --gt;  lt;!-- lt;bean id="tibcoDataListenerTimer" class="org.springframework.jms.listener.DefaultMessageListenerContainer" --gt; lt;!-- depends-on="transactionManager, TimerTibcoRemoteConnectionFactory, TimerTibcoRemoteQueue, timerModuleListener"gt; --gt; lt;!-- lt;property name="connectionFactory" ref="TimerTibcoRemoteConnectionFactory"/gt; --gt; lt;!-- lt;property name="destination" ref="TimerTibcoRemoteQueue"/gt; --gt; lt;!-- lt;property name="messageListener" ref="timerModuleListener"/gt; --gt; lt;!-- lt;property name="sessionTransacted" value="true"/gt; --gt; lt;!-- lt;property name="transactionManager" ref="transactionManager"/gt; --gt; lt;!-- lt;property name="maxConcurrentConsumers" value="5"/gt; --gt; lt;!-- lt;property name="concurrentConsumers" value="1"/gt; --gt; lt;!-- lt;/beangt; --gt;     lt;/beansgt;