プロトコルアダプターの使用
これまでに示したすべての例は、DSL が Spring Integration プログラミングモデルを用いてメッセージングアーキテクチャをサポートする方法を示しています。しかし、まだ実際の統合は行われていません。統合には、HTTP、JMS、AMQP、TCP、JDBC、FTP、SMTP などを介してリモートリソースにアクセスするか、ローカルファイルシステムにアクセスする必要があります。Spring Integration はこれらすべてに加え、さらに多くの機能をサポートしています。理想的には、DSL はこれらすべてに対してファーストクラスのサポートを提供する必要がありますが、これらすべてを実装し、Spring Integration に新しいアダプターが追加されるたびに対応していくのは困難な作業です。そのため、DSL は Spring Integration に継続的に追いつくことが期待されます。
そのため、プロトコル固有のメッセージングをシームレスに定義するための高水準 API を提供しています。これは、ファクトリパターンとビルダーパターン、ラムダ式を用いて実現しています。ファクトリクラスは、具体的なプロトコル固有の Spring Integration モジュールのコンポーネントに対する XML 名前空間と同じロールを果たすため、「名前空間ファクトリ」と考えることができます。現在、Spring Integration Java DSL は Amqp、Feed、Jms、Files、(S)Ftp、Http、JPA、MongoDb、TCP/UDP、Mail、WebFlux、Scripts 名前空間ファクトリをサポートしています。次の例は、そのうちの 3 つ(Amqp、Jms、Mail)の使用方法を示しています。
@Bean
public IntegrationFlow amqpFlow() {
return IntegrationFlow.from(Amqp.inboundGateway(this.rabbitConnectionFactory, queue()))
.transform("hello "::concat)
.transform(String.class, String::toUpperCase)
.get();
}
@Bean
public IntegrationFlow jmsOutboundGatewayFlow() {
return IntegrationFlow.from("jmsOutboundGatewayChannel")
.handle(Jms.outboundGateway(this.jmsConnectionFactory)
.replyContainer(c ->
c.concurrentConsumers(3)
.sessionTransacted(true))
.requestDestination("jmsPipelineTest"))
.get();
}
@Bean
public IntegrationFlow sendMailFlow() {
return IntegrationFlow.from("sendMailChannel")
.handle(Mail.outboundAdapter("localhost")
.port(smtpPort)
.credentials("user", "pw")
.protocol("smtp")
.javaMailProperties(p -> p.put("mail.debug", "true")),
e -> e.id("sendMailEndpoint"))
.get();
} 上記の例は、「名前空間ファクトリ」をインラインアダプター宣言として使用する方法を示しています。ただし、@Bean 定義からこれらを使用して、IntegrationFlow メソッドチェーンをより読みやすくすることができます。
| 他の人に努力する前に、これらの名前空間ファクトリに関するコミュニティのフィードバックを募集しています。また、次にサポートする必要のあるアダプターとゲートウェイの優先順位付けに関する意見も歓迎します。 |
このリファレンスマニュアル全体のプロトコル固有の章で、さらに多くの Java DSL サンプルを見つけることができます。
他のすべてのプロトコルチャネルアダプターは、次の例に示すように、汎用 Bean として構成され、IntegrationFlow に接続されます。
@Bean
public QueueChannelSpec wrongMessagesChannel() {
return MessageChannels
.queue()
.wireTap("wrongMessagesWireTapChannel");
}
@Bean
public IntegrationFlow xpathFlow(MessageChannel wrongMessagesChannel) {
return IntegrationFlow.from("inputChannel")
.filter(new StringValueTestXPathMessageSelector("namespace-uri(/*)", "my:namespace"),
e -> e.discardChannel(wrongMessagesChannel))
.log(LoggingHandler.Level.ERROR, "test.category", m -> m.getHeaders().getId())
.route(xpathRouter(wrongMessagesChannel))
.get();
}
@Bean
public AbstractMappingMessageRouter xpathRouter(MessageChannel wrongMessagesChannel) {
XPathRouter router = new XPathRouter("local-name(/*)");
router.setEvaluateAsString(true);
router.setResolutionRequired(false);
router.setDefaultOutputChannel(wrongMessagesChannel);
router.setChannelMapping("Tags", "splittingChannel");
router.setChannelMapping("Tag", "receivedChannel");
return router;
}