2017-02-05 1 views
0

스프링 토끼 bean 및 구성에 xml 파일을 사용하여 Spring Rabbit을 구성합니다.'Getter Bean'에서 속성 가져 오기시 Spring Rabbit Queue Xml : NoSuchBeanDefinition

우리는 우리 자신의 propertyGetter 클래스를 사용하여 속성을 검색합니다. 아래의 봄 토끼 xml에서는 한 곳을 제외하고 어디에서나 작동합니다. 왜 이런거야?

아래는 XML입니다. 호출 된 'propertyGetter.get (...)'메소드가 'my.queue'문자열을 반환하지만 RabbitMq xsd 파서가 빈을 얻으려는 것 같습니다. (?).

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:rabbit="http://www.springframework.org/schema/rabbit" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans.xsd 
     http://www.springframework.org/schema/rabbit 
     http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.xsd"> 

     <!-- This has the 'propertyGetter' bean --> 
     <import resource="**/applicationContext.xml"/> 

     <!-- RabbitMQ --> 
     <rabbit:connection-factory id="rabbitConnectionFactory" addresses="#{propertyGetter.get('rabbitMq.hostName')}" username="#{propertyGetter.get('rabbitMq.userName')}" password="#{propertyGetter.get('rabbitMq.password')}" virtual-host="#{propertyGetter.get('rabbitMq.vHost')}"/> 
     <rabbit:admin connection-factory="rabbitConnectionFactory"/> 

     <!-- RabbitMQ Template --> 
     <rabbit:template id="rabbitTemplate" connection-factory="rabbitConnectionFactory" message-converter="messageConverter" exchange="#{propertyGetter.get('rabbitMq.exchange')}"/> 


     /******************************************* 
     * 
     * THIS IS THE ONLY PLACE IT DOESN'T WORK 
     * <rabbit:queue name="" 
     *  It does seem to get value 'my.queue' 
     *  but the exception that's posted 
     *  below indicates it's trying to 
     *  construct a bean! Why is this? 
     *******************************************/ 
     <!-- RabbitMQ Queue Definitions --> 
     <!--<rabbit:queue name="my.queue" >--> <!--THIS WORKS--> 
     <rabbit:queue name="#{propertyGetter.get('rabbitMq.queue.name')}" > <!--THIS DOESN'T--> 
      <rabbit:queue-arguments> 
       <entry key="x-ha-policy" value="all"/> 
      </rabbit:queue-arguments> 
     </rabbit:queue> 

     <!-- RabbitMQ Exchange and Binding Definition --> 
     <rabbit:direct-exchange name="#{propertyGetter.get('rabbitMq.exchange')}"> 
      <rabbit:bindings> 
       <rabbit:binding key="#{propertyGetter.get('rabbitMq.routing.key')}" queue="#{propertyGetter.get('rabbitMq.queue.name')}"/> 
      </rabbit:bindings> 
     </rabbit:direct-exchange> 

     <!-- Listeners --> 
     <rabbit:listener-container id="listener" connection-factory="rabbitConnectionFactory" concurrency="3" max-concurrency="5" requeue-rejected="false"> 
      <rabbit:listener ref="eventNotificationAdapter" queues="#{propertyGetter.get('rabbitMq.queue.name')}" priority="#{propertyGetter.get('rabbitMq.queue.priority')}" /> 
     </rabbit:listener-container> 

     <!-- Message Listener Adapters --> 
     <bean id="eventNotificationAdapter" class="org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter"> 
      <constructor-arg name="delegate" ref="myQueueConsumer"/> 
      <constructor-arg name="messageConverter" ref="messageConverter"/> 
      <property name="defaultListenerMethod" value="process"/> 
     </bean> 

     <bean id="messageConverter" class="org.springframework.amqp.support.converter.JsonMessageConverter"/> 

</beans> 

응용 프로그램이 처음 is'NoSuchBeanDefinitionException를 '초기화,하지만 난 모르겠어요 예외 왜 메서드 호출이 문자열을 반환되면, XML이 빈을 기대하고 구문 분석 뭐든간에. 이 솔루션은 않습니다

스프링 토끼 1.3.xsd을 사용하는 XML 파일입니다 :

SEVERE: Exception sending context initialized event to listener instance of class org.jboss.resteasy.plugins.spring.SpringContextLoaderListener 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.amqp.rabbit.config.BindingFactoryBean#0': Cannot resolve reference to bean '#{propertyGetter.get('rabbitMq.queue.name')}' while setting bean property 'destinationQueue'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'my.queue' is defined 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1477) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1222) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:736) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) 
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) 
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) 
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106) 
    at org.jboss.resteasy.plugins.spring.SpringContextLoaderListener.contextInitialized(SpringContextLoaderListener.java:48) 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5017) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5531) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) 
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) 
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652) 
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1095) 
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1930) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'my.queue' is defined 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:687) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1168) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:281) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351) 
    ... 29 more 

기타 사항 : 여기

앱을 배포 할 때 내가 얻을 스택 추적입니다 스프링 특성을 사용하지 마십시오. 이것은 속성을 다른 방법으로 관리하기위한 것입니다.

+0

propertyGetter가 초기화되는 applicationContext.xml을 추가 할 수 있습니까? –

답변

1

두 가지가 있습니다.

<bean/>의 경우 name 속성은 bean 이름의 별명입니다. id이 제공되지 않으면 첫 번째 name이 id로 사용됩니다.

<queue/>의 경우 name 속성은 rabbitmq 브로커의 대기열 이름입니다. id은 항상 bean 이름이며, 존재하지 않으면 고유 한 bean 이름이 생성됩니다.

별칭으로 name을 등록하는 기존 논리가 있지만 구문 분석 시간에 값을 알고있을 때만 작동합니다 (사용자가 발견 한대로).

실제로 이러한 별칭 사용은 올바르지 않으며 다른 문제가 발생합니다. 예를 들어 name과 같은 교환 및 대기열을 가질 수 없습니다 (this JIRA for a discussion about that 참조).

이 문제를 해결하기 위해 우리는 앨리어싱을 모두 제거하고 콩에 이름을 부여하기 위해 id 속성을 요구합니다.

대기열에 id을 지정하고 리스너 컨테이너 queues 속성을 참조하거나 queue-names을 사용하도록 컨테이너를 변경하여 문제를 해결할 수 있습니다.

+0

이것은 효과가 있습니다! 나는 여전히 큐 자체에서 propertyGetter를 사용할 수 있었지만, ID를 추가하고 리스너 컨테이너와 교환 바인딩에 ID를 추가했습니다. 내가 언급 한 것을 잊어 버렸습니다. 내 질문에 XML은 속성 파일과 $ {my.prop}을 사용하여 작동합니다. 이유가 같은 런타임 오류를 일으키지 않는지 확실하지 않습니다. – Matt

+0

예, 별칭의 자리 표시자를 해결하기위한 bean 팩토리의 논리가 있지만 SpEL 표현식에 해당하는 것이 없습니다. –

관련 문제