iT邦幫忙

2022 iThome 鐵人賽

DAY 16
0
自我挑戰組

Spring In Action系列 第 16

Intro of integration flow

  • 分享至 

  • xImage
  •  

這章節要來說明integration flow,就是如果我們的系統需要與其他系統介接,就可透過Spring Integration來做到這件事,目前這段會以和file system介接為例。

我們需要以下的dependency來做到spring integration flow:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-file</artifactId>
</dependency>

首先第一件事就是要先做出一個Spring App與integration flow溝通的橋樑,在這邊的英文會叫做gateway,如下設定:

package sia6;
 
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.file.FileHeaders;
import org.springframework.messaging.handler.annotation.Header;
 
@MessagingGateway(defaultRequestChannel="textInChannel")
public interface FileWriterGateway {
 
  void writeToFile(
      @Header(FileHeaders.FILENAME) String filename,
      String data);
 
}

再來開始設定integration flow,這邊的範例會有一個input channel,接上一個把字變成upper case的transformer,再接上一個output channel。而設定integration flow有三種方法:

1.XML

<?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:int="http://www.springframework.org/schema/integration"
  xmlns:int-file="http://www.springframework.org/schema/integration/file"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/integration
    http://www.springframework.org/schema/integration/spring-integration.xsd
    http://www.springframework.org/schema/integration/file
    http://www.springframework.org/schema/integration/file/spring-integration-file.xsd">
 
    <int:channel id="textInChannel" />
 
    <int:transformer id="upperCase"
        input-channel="textInChannel"
        output-channel="fileWriterChannel"
        expression="payload.toUpperCase()" />
  
    <int:channel id="fileWriterChannel" />
  
    <int-file:outbound-channel-adapter id="writer"
        channel="fileWriterChannel"
        directory="/tmp/sia6/files"
        mode="APPEND"
        append-new-line="true" />
  
</beans>

2.Java

package sia6;
 
import java.io.File;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.file.FileWritingMessageHandler;
import org.springframework.integration.file.support.FileExistsMode;
import org.springframework.integration.transformer.GenericTransformer;
 
@Configuration
public class FileWriterIntegrationConfig {
 
  @Bean
  @Transformer(inputChannel="textInChannel",
               outputChannel="fileWriterChannel")
  public GenericTransformer<String, String> upperCaseTransformer() {
    return text -> text.toUpperCase();
  }
 
  @Bean
  @ServiceActivator(inputChannel="fileWriterChannel")
  public FileWritingMessageHandler fileWriter() {
    FileWritingMessageHandler handler =
        new FileWritingMessageHandler(new File("/tmp/sia6/files"));
    handler.setExpectReply(false);
    handler.setFileExistsMode(FileExistsMode.APPEND);
    handler.setAppendNewLine(true);
    return handler;
  }
 
}

以上會發現我們沒有像XML去獨立設定textInChannel和fileWriterChannel,因為Spring會自動幫我們建立出這兩個Bean,不過當然若需要customize的話,可如下建立:

@Bean
public MessageChannel textInChannel() {
  return new DirectChannel();
}
...
@Bean
public MessageChannel fileWriterChannel() {
  return new DirectChannel();
}

3.Spring integration’s Java DSL(domain specific language)

package sia6;
 
import java.io.File;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.dsl.MessageChannels;
import org.springframework.integration.file.dsl.Files;
import org.springframework.integration.file.support.FileExistsMode;
 
@Configuration
public class FileWriterIntegrationConfig {
 
  @Bean
  public IntegrationFlow fileWriterFlow() {
    return IntegrationFlows
        .from(MessageChannels.direct("textInChannel"))
        .<String, String>transform(t -> t.toUpperCase())
        .handle(Files
            .outboundAdapter(new File("/tmp/sia6/files"))
            .fileExistsMode(FileExistsMode.APPEND)
            .appendNewLine(true))
        .get();
  }
 
}

會發現我們只需要設定一個Bean就搞定整個flow了。如果我們覺得沒有寫出output channel會在解讀程式上有遺漏,那可如下補上:

@Bean
public IntegrationFlow fileWriterFlow() {
  return IntegrationFlows
      .from(MessageChannels.direct("textInChannel"))
      .<String, String>transform(t -> t.toUpperCase())
      .channel(MessageChannels.direct("FileWriterChannel"))
      .handle(Files
          .outboundAdapter(new File("/tmp/sia6/files"))
          .fileExistsMode(FileExistsMode.APPEND)
          .appendNewLine(true))
      .get();
}

上一篇
KafkaTemplate
下一篇
Components of integration flow
系列文
Spring In Action30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言