2

私は最近、Spring と spring-amqp の学習を始めたので、この質問は非常に基本的なものに見えるかもしれません。

異なるホスト上にあり、異なる QueueName、RoutingKey、vhost、user、password を持つ複数のキューがあります。これらのキューのパブリッシング ロジックを作成していますが、キューごとに 1 つの構成クラスを使用する必要があるのか​​、それとも XML で実行できるのかを判断できませんでした。

キューに関するすべての情報 (ホスト、仮想ホスト、ユーザー名など) を持つクラスを作成する方法は、この例で説明されているように正常に機能しています。@Configuration クラスを作成し、そのキューのすべての Bean を定義しました。しかし、私はする必要があります

ApplicationContext context = new AnnotationConfigApplicationContext(MyQueueConfiguration.class);
AmqpTemplate amqpTemplate  = context.getBean(AmqpTemplate.class);
amqpTemplate.convertAndSend("Hello World!!");

だから私の要件は次のとおりです。

  1. アプリケーションの起動時にインスタンス化する必要がある多くのキューがあるため、Tomcat が起動したら、キュー/ウサギ クラスタへの接続/チャネルを確立する必要があります。
  2. 次に、アプリケーションに POST リクエストが来るとすぐに、POST パラメータに基づいてキューの 1 つにメッセージを発行する必要があります。

したがって、キューごとに常に次のことを行う必要があります。

ApplicationContext context = new AnnotationConfigApplicationContext(HelloWorldConfiguration.class);

または、すべてのキュー構成クラスをSpringでロードし、次のようなオブジェクトを使用する方法はありますか:

    // calling code when I get a POST request
MyQueueConfigurationClass.publishMessage(payload, queueName);

// The implementation code
public boolean publishMessage(String payload, String queueName){

    // Get Bean for the **queueName** somehow
    AmqpTemplate amqpTemplate = context.getBean(AmqpTemplate.class);
    // Use the bean to send the message
    amqpTemplate.convertAndSend(payload);

}
  1. では、毎回実行せずに正確なキューの amqpTemplate を取得するにはどうすればよいnew AnnotationConfigApplicationContext()でしょうか?
  2. サービスにリクエストが来るたびに新しい AnnotationConfigApplicationContext を実行することの害は何ですか? [リクエストごとに新しいオブジェクトを作成するのは良い考えではないと推測しています]
4

1 に答える 1

3

毎回新しいコンテキストを作成しないでください。それは非常に無駄です。

複数の接続ファクトリ (ウサギ ホストごとに 1 つ) をルート (または Web) コンテキストに追加し、ルーティング接続ファクトリを とともに使用sendConnectionFactorySelectorExpressionして、送信するメッセージに基づいて適切なホストを選択できます。

RabbitTemplateまたは、サーバーごとに異なるものを単純に配線することもできます。

編集

を使用するSimpleRoutingConnectionFactoryには、次のようにします...

try {
    SimpleResourceHolder.bind(routingCF, keyForThisMessage);
    rabbitTemplate.convertAndSend(message);
}
finally {
    SimpleResourceHolder.unbind(routingCF);
}

(これは変更されていない で機能しRabbitTemplateます)または...

<rabbit:template id="routingTemplate"
    connection-factory="rcf"
    send-connection-factory-selector-expression="messageProperties.headers['cfKey']" />

<bean id="rcf" class="org.springframework.amqp.rabbit.connection.SimpleRoutingConnectionFactory">
    <property name="targetConnectionFactories">
        <map>
            <entry key="foo" value-ref="cf1"/>
            <entry key="bar" value-ref="cf2"/>
        </map>
    </property>
    <property name="defaultTargetConnectionFactory" ref="defaultCF"/>
</bean>

...その後...

this.routingTemplate.convertAndSend("exchange", "routingKey", "xyz", new MessagePostProcessor() {

    @Override
    public Message postProcessMessage(Message message) throws AmqpException {
        message.getMessageProperties().setHeader("cfKey", "foo");
        return message;
    }

});

ここに完全なテストケースがあります。

于 2015-03-18T23:20:28.447 に答える