#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;