2017-02-05 3 views
0

私はspring rabbit beansとconfiguration用にxmlファイルを使用してSpring Rabbitを設定しています。Spring Rabbit Queue Xml: 'Getter Bean'からプロパティを取得するときのNoSuchBeanDefinition

独自のpropertyGetterクラスを使用してプロパティを取得します。以下の春のウサギxmlでは、1か所を除いてどこでも動作します。どうしてこれなの?

以下はxmlです。呼び出されている 'propertyGetter.get(...)'メソッドがString 'my.queue'を返していますが、RabbitMq xsdパーサがBeanを取得しようとしているようです。 (?)。

<?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を解析している理由は、私はわからない例外は、Beanを期待しています。

ここでアプリを展開しようとしたとき、私は取得スタックトレースです:

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 

その他の注意事項: これは

春ウサギ-1.3.xsdを使用するXMLファイルであるソリューションはありません春のプロパティを使用しないでください。これは別の方法でプロパティを管理するためのものです。

+0

applicationContext.xmlを追加してください。ここで、propertyGetterは初期化されていますか? –

答えて

1

これは2つの異なるものです。

<bean/>の場合、name属性はBean名のエイリアスです。 idが指定されていない場合、最初のnameがidとして使用されます。

<queue/>の場合、name属性は、rabbitmqブローカのキュー名です。 idは常にBean名であり、存在しない場合は固有のBean名が生成されます。

nameをエイリアスとして登録するための既存のロジックがいくつかありますが、値が解析時にわかっている場合にのみ動作します(見つかった場合)。

実際には、このエイリアシングの使用は間違っており、他の問題が発生します。たとえば、nameと同じ交換とキューを持つことはできません。this JIRA for a discussion about thatを参照してください。

この問題を解決するために、エイリアスを完全に削除し、id属性を使用してBeanに名前を付けることを検討しています。

キューにidを与え、リスナーコンテナqueuesの属性を参照するか、代わりにqueue-namesを使用するようにコンテナを変更することで問題を回避できます。

+0

これはうまくいった!私はまだキュー自体でpropertyGetterを使用することができましたが、IDを追加してリスナーコンテナと交換バインディングにも使用しました。私の質問にあるXMLは、プロパティファイルと$ {my.prop}を使って動作することを忘れていました。それがなぜ同じランタイムエラーを引き起こさないのか分かりません。 – Matt

+0

はい、Beanファクトリにエイリアスのプレースホルダを解決するロジックがありますが、SpEL式には同等のものはありません。 –

関連する問題