JMSリスナーを必要とするアプリケーションに対して、Spring 4.1で提供される新しいアノテーションと機能を使用したいと思います。
Spring 4.1 JMS Improvements post のメモを注意深く読みましたが、_@JmsListener
_とおそらくDestinationResolver
の関係、および適切なDestination
を示すようにアプリケーションを設定する方法を逃し続けていますまたはEndpoint
。
@JmsListenerの推奨される使用法を以下に示します
_@Component
public class MyService {
@JmsListener(containerFactory = "myContainerFactory", destination = "myQueue")
public void processOrder(String data) { ... }
}
_
"myQueue"はEnvironment.getProperty()
を使用して構成ファイルから読み取る必要があるため、実際のコードではこれを使用できません。
DestinationResolver
を使用して適切なmyContainerFactoryを設定できますが、ほとんどの場合、アプリケーションサーバーのキューを検索するためにJNDIが必要なく、カスタムの返信ロジックを実行する必要がない場合は、DynamicDestinationResolver
を使用するだけのようです。私は単に、Springが_@JmsListener
_アノテーションを使用して、パラメーター化された方法でキューの名前を指定する方法を理解しようとしているだけです。
ブログ記事のさらに下の方に、このConfigurerへの参照があります。
_@Configuration
@EnableJms
public class AppConfig implements JmsListenerConfigurer {
@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
registrar.setDefaultContainerFactory(defaultContainerFactory());
SimpleJmsListenerEndpoint endpoint = new SimpleJmsListenerEndpoint();
endpoint.setDestination("anotherQueue");
endpoint.setMessageListener(message -> {
// processing
});
registrar.registerEndpoint(endpoint);
}
_
これはある程度の意味があり、実行時に外部文字列からDestinationを設定できる場所がわかりましたが、これは_@JmsListener
_の使用と競合しているようです。上記のコードでは_endpoint.setMessageListener
_を支持します。
_@JmsListener
_を使用して適切なキュー名を指定する方法に関するヒントはありますか?
あなたは最終的に今それを行うことができますが、それは少し複雑です。 JmsListenerEndpointRegistry
を使用してカスタムJmsListenerConfigurer
を設定できます
@Configuration
@EnableJms
public class AppConfig implements JmsListenerConfigurer {
@Override
public void configureJmsListeners(JmsListenerEndpointRegistrar registrar) {
registrar.setEndpointRegistry(customRegistry());
}
}
次に、次のようなregisterListenerContainerメソッドをオーバーライドします。
public void registerListenerContainer(JmsListenerEndpoint endpoint, JmsListenerContainerFactory<?> factory) {
// resolve destination according to whatever -> resolvedDestination
((AbstractJmsListenerEndpoint)endpoint).setDestination(resolvedDestination);
super.registerListenerContainer(endpoint, factory);
}
しかし、私たちはもっとうまくやることができました。 SPR-1228 を見て/投票してください
また、ユースケースによっては、環境ごとのプロパティファイルとPropertySourcesPlaceholderConfigurerを使用してすでにパラメータ化できることに注意してください。
@JmsListener(destinations = "${some.key}")
スプリングブートで@JmsListener
を使用している場合は、PropertySourcesPlaceholderConfigurer
を構成する必要はありません。すぐに使える
サンプル:
クラス
@JmsListener(destination = "${spring.activemq.queue.name}")
public void receiveEntityMessage(final TextMessage message) {
// process stuff
}
}
application.properties
spring.activemq.queue.name=some.weird.queue.name.that.does.not.exist
スプリングブート出力
[26-Aug;15:07:53.475]-[INFO ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[931 ]-Successfully refreshed JMS Connection
[26-Aug;15:07:58.589]-[WARN ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[880 ]-Setup of JMS message listener invoker failed for destination 'some.weird.queue.name.that.does.not.exist' - trying to recover. Cause: User user is not authorized to read from some.weird.queue.name.that.does.not.exist
[26-Aug;15:07:59.787]-[INFO ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[931 ]-Successfully refreshed JMS Connection
[26-Aug;15:08:04.881]-[WARN ]-[,]-[DefaultMes]-[o.s.j.l.DefaultMessageListenerContainer ]-[880 ]-Setup of JMS message listener invoker failed for destination 'some.weird.queue.name.that.does.not.exist' - trying to recover. Cause: User user is not authorized to read from some.weird.queue.name.that.does.not.exist
これは、@ JmsListenerが明示的にPropertySourcesPlaceholderConfigurer
を設定せずにapplication.propertiesからプロパティ値を取得できることを証明しています
これが役に立てば幸いです!