1. 概要

以前の記事で、 SpringRemotingを使用して非同期チャネル上にRPCAMQPキューとして提供する方法を説明しました。 ただし、JMSを使用しても同じ結果を得ることができます。

この記事では、実際に、 Spring RemotingJMSおよびApacheActiveMQをメッセージングミドルウェアとして使用してリモート呼び出しを設定する方法について説明します。

2. ApacheActiveMQブローカーの起動

Apache ActiveMQ は、アプリケーションが非同期で情報を交換できるようにするオープンソースメッセージブローカーであり、JavaメッセージサービスAPI[X209Xと完全に互換性があります。 ]。

実験を実行するには、最初にActiveMQの実行インスタンスをセットアップする必要があります。 いくつかの方法から選択できます。公式ガイドで説明されている手順に従うか、 Java アプリケーションに埋め込むか、Dockerコンテナを次のコマンド:

docker run -p 61616:61616 -p 8161:8161 rmohr/activemq:5.14.3

これにより、 ActiveMQ コンテナーが起動し、ポート8081で簡単な管理Web GUIが公開されます。これにより、使用可能なキュー、接続されているクライアント、およびその他の管理情報を確認できます。 JMS クライアントは、代わりにポート61616を使用してブローカーに接続し、メッセージを交換する必要があります。

3. Mavenの依存関係

Spring Remoting に関する以前の記事と同様に、サーバーとクライアント Spring Boot アプリケーションをセットアップして、 JMSRemotingがどのように機能するかを示します。

通常、 Spring Boot スターターの依存関係を慎重に選択します。ここで説明するように、

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-activemq</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

クラスパスにTomcat関連の.jarファイルが含まれないようにするために、spring-boot-starter-tomcatを明示的に除外しました。

これにより、 Spring Boot の自動構成メカニズムが、アプリケーションの起動時に組み込みWebサーバーを必要としないため、起動できなくなります。

4. サーバーアプリケーション

4.1. サービスを公開する

クライアントが呼び出すことができるCabBookingServiceを公開するサーバーアプリケーションをセットアップします。

最初のステップは、クライアントに公開するサービスのインターフェースを実装するBeanを宣言することです。これは、サーバー上でビジネスロジックを実行するBeanです。

@Bean 
CabBookingService bookingService() {
    return new CabBookingServiceImpl();
}

次に、コンストラクターで名前を指定して、サーバーが呼び出しを取得するキューを定義しましょう。

@Bean 
Queue queue() {
    return new ActiveMQQueue("remotingQueue");
}

以前の記事からすでに知っているように、 Spring Remotingの主要な概念の1つは、サービスエクスポーターです。これは、あるソース、この場合はApacheMQ[X224Xから呼び出し要求を収集するコンポーネントです。 ]キュー─そしてサービス実装で目的のメソッドを呼び出します。

JMS を操作するには、JmsInvokerServiceExporterを定義します。

@Bean 
JmsInvokerServiceExporter exporter(CabBookingService implementation) {
    JmsInvokerServiceExporter exporter = new JmsInvokerServiceExporter();
    exporter.setServiceInterface(CabBookingService.class);
    exporter.setService(implementation);
    return exporter;
}

最後に、メッセージを消費する責任を持つリスナーを定義する必要があります。 リスナーは、ApacheMQと JmsInvokerServiceExporter の間のブリッジとして機能し、キューで使用可能な呼び出しメッセージをリッスンし、呼び出しをサービスエクスポーターに転送し、結果をシリアル化して戻します。

@Bean SimpleMessageListenerContainer listener(
  ConnectionFactory factory, 
  JmsInvokerServiceExporter exporter) {
 
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(factory);
    container.setDestinationName("remotingQueue");
    container.setConcurrentConsumers(1);
    container.setMessageListener(exporter);
    return container;
}

4.2. 構成

application.properties ファイルを設定して、 Spring Boot がいくつかの基本的なオブジェクト(たとえば、リスナーが必要とする ConnectionFactory )を構成できるようにすることを忘れないでください。 さまざまなパラメータの値は、主に方法によって異なります

さまざまなパラメーターの値は、主に ApacheMQ のインストール方法によって異なります。次の値は、実行する同じマシンで実行されるDockerコンテナーの適切な構成です。これらの例:

spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.packages.trusted=org.springframework.remoting.support,java.lang,com.baeldung.api

spring.activemq.broker-url パラメーターは、AMQポートへの参照です。 代わりに、 spring.activemq.packages.trustedパラメーターについて、より詳細な説明が必要です。 バージョン5.12.2以降、ActiveMQはデフォルトでタイプのメッセージを拒否します

バージョン5.12.2以降、ActiveMQは、シリアル化された Java オブジェクトの交換に使用される、タイプ ObjectMessage のメッセージをデフォルトで拒否します。これは、一部のコンテキストでセキュリティ攻撃の潜在的なベクトルと見なされるためです。

とにかく、指定されたパッケージでシリアル化されたオブジェクトを受け入れるようにAMQに指示することは可能です。 org.springframework.remoting.support は、リモートメソッドの呼び出しとその結果を表すメインメッセージを含むパッケージです。 その包み

パッケージcom.baeldung.apiには、パラメーターとサービスの結果が含まれています。 java.lang が追加されたのは、タクシー予約の結果を表すオブジェクトが String を参照しているためです。したがって、これもシリアル化する必要があります。

5. クライアントアプリケーション

5.1. リモートサービスを呼び出す

それでは、クライアントに取り組みましょう。 ここでも、呼び出しメッセージが書き込まれるキューを定義する必要があります。 クライアントとサーバーの両方が同じ名前を使用していることを再確認する必要があります。

@Bean 
Queue queue() {
    return new ActiveMQQueue("remotingQueue");
}

次に、エクスポーターを設定する必要があります。

@Bean 
FactoryBean invoker(ConnectionFactory factory, Queue queue) {
    JmsInvokerProxyFactoryBean factoryBean = new JmsInvokerProxyFactoryBean();
    factoryBean.setConnectionFactory(factory);
    factoryBean.setServiceInterface(CabBookingService.class);
    factoryBean.setQueue(queue);
    return factoryBean;
}

これで、リモートサービスをローカルBeanとして宣言されているかのように使用できます。

CabBookingService service = context.getBean(CabBookingService.class);
out.println(service.bookRide("13 Seagate Blvd, Key Largo, FL 33037"));

5.2. 例を実行する

また、クライアントアプリケーションの場合、アプリケーションの値を適切に選択する必要があります.propertiesファイル。 一般的な設定では、これらはサーバー側で使用されているものと完全に一致します。

これは、 ApacheAMQを介したリモート呼び出しを示すのに十分なはずです。 それでは、最初に ApacheMQ を起動し、次にサーバーアプリケーションを起動し、最後にリモートサービスを呼び出すクライアントアプリケーションを起動します。

6. 結論

このクイックチュートリアルでは、 Spring Remoting を使用して、JMSシステムの上にRPCAMQとして提供する方法を説明しました。

Spring Remotingは、基になるチャネルに関係なく、非同期呼び出しをすばやく簡単に設定できることを示し続けています。

いつものように、ソースはGitHubにあります。