ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [스프링 인 액션] Chapter 9 - 스프링 통합하기 :: 스프링 통합의 컴포넌트 살펴보기
    개발서적읽기/Spring in Action 제 5판 2020. 9. 27. 23:45



    통합 플로우는 하나 이상의 컴포넌트로 구성되며, 그 리스트는 아래와 같다.


    • 채널(Channel) : 한 요소로부터 다른 요소로 메시지를 전달한다.

    • 필터(Filter) : 조건에 맞는 메시지가 플로우를 통과하게 해준다.

    • 변환기(Transformer) : 메시지 값을 변경하거나 메시지 페이로드의 타입을 다른
      타입으로 변환한다.

    • 라우터(Router) : 여러 채널 중 하나로 메시지를 전달하며, 대개 메시지 헤더를
      기반으로 한다.

    • 분배기(Spliter) : 들어오는 메시지를 두 개 이상의 메시지로 분할하며, 분할된 각 메시지는
      다른 채널로 전송된다.

    • 집적기(Aggregator) : 분배기와 상반된 것으로 별개의 채널로부터 전달되는 다수의
      메시지를 하나의 메시지로 결합한다.

    • 서비스 액티베이터(Service activator) : 메시지를 처리할 수 있도록 자바 메서드에
      메시지를 넘겨준 후 메서드의 반환값을 출력 채널로 전송한다.

    • 게이트웨이(Gateway) : 인터페이스를 통해 통합 플로우로 데이터를 전달한다.


    이전 포스팅(파일-쓰기 통합 플로우)에서 이미 이 컴포넌트들 중 몇 개의 사용 예를 이미 

    알아보았다. 아래에 간략히 정리되어있다.

    FileWriterGateway 인터페이스는 애플리케이션이 제출했던 텍스트 데이터를 파일에 쓰기

    위한 게이트웨이다. 또한 지정된 텍스트를 대문자로 변환하는 변환기도 정의하였다.

    그 다음에 텍스트를 파일에 쓰는 작업을 수행했던 서비스 게이트웨이를 선언하였다.

    이렇게 정의했던 파일-쓰기 통합 플로우는 서로 다른 컴포넌트들을 상호 연결하는

    두 개의 채널인 textInChannel과 fileWriterChannel을 갖는다.


    지금부터는 통합 플로우 컴포넌트에 통합플로우 컴포넌트에 관해 알아본다.




    ■메시지 채널


    메시지 채널은 통합 플로우의 서로 다른 컴포넌트 간에 데이터(메시지)를 전달하는 통로다.




    스프링 통합은 아래와 같은 여러 채널 구현체를 제공한다.


    • PublishSubscribeChannel : 메시지를 하나 이상의 컨슈머(메시지를 소비하는 컴포넌트나
      애플리케이션)로 전달한다. 컨슈머가 다수일 때는 모든 컨슈머가 해당 메시지를 수신한다.

    • QueueChannel : 이것으로 전송되는 메시지는 FIFO 방식으로 컨슈머가 가져갈 때까지
      큐에 저장된다. 컨슈머가 여럿일 때는 그중 하나의 컨슈머만 해당 메시지를 수신한다.

    • PriorityChannel : QueueChannel과 유사하지만, FIFO 방식 대신 메시지의 priority 헤더를
      기반으로 컨슈머가 메시지를 가져간다.

    • RendezvousChannel : QueueChannel과 유사하지만, 컨슈머가 메세지를 수신할 때까지
      메시지 전송자가 채널을 차단한다는 것이 다르다(전송자와 컨슈머를 동기화한다.)

    • DirectChannel : PublishSubscribeChannel과 유사하지만, 전송자와 동일한 스레드로
      실행되는 컨슈머를 호출하여 단일 컨슈머에게 메시지를 전송한다. 이 채널은 트랜잭션을 지원한다.

    • ExecutorChannel : DirectChannel과 유사하지만, TaskExecutor를 통해서 메시지가
      전송된다.(전송자와 다른 스레드에서 처리된다) 이 채널은 트랜잭션을 지원하지 않는다.

    • FluxMessageChannel : 프로젝트 리액터(Project Reactor)의 플럭스(Flux)를 기반으로
      하는 리액티브 스트림즈 퍼블리셔(Reactive Streams Publisher) 채널이다.
      (Project Reactor, Flux, Chaper, Reactive Streams는 Chapter 10에서 자세히 다룬다.)


    Java 구성과 Java DSL 구성은 입력 채널이 자동으로 생성된다. 그리고 채널 기본 구현체로 


    Direct Channel이 설정된다. 그러나 다른 채널 구현체를 사용하고 싶다면 해당 채널을 


    별도의 빈으로 선언하고 통합 플로우에서 참조해야 한다. 예를 들어 


    PublishSubscribeChannel을 선언하려면 다음과 같이 @Bean이 지정된 메서드를 선언한다.

    @Bean
    public MessageChannel orderChannel() {
    return new PublishSubscribeChannel();
    }

    그다음에 통합 플로우 정의에서 이 채널을 이름으로 참조한다. 예를 들어, 이 채널을 


    서비스 액티베이터에서 소비한다면 @ServiceActivator 애노테이션의 inputChannel 


    속성에서 이 채널 이름으로 참조하면 된다.

    @ServiceActivator(inputChannel = "orderChannel")

    또는 자바 DSL 구성을 사용할 때는 Channel() 메서드의 호출에서 참조한다.

    @Bean
    public IntegrationFlow orderFlow() {
    return IntegrationFlows
    ...
    .channel("orderChannel")
    ...
    .get();
    }

    QueueChannel을 사용할 때는 컨슈머가 이 채널을 polling 하도록 구성해야 한다.


    예를 들어 다음과 같이 QueueChannel 빈을 선언했다고 해보자.

    @Bean
    public MessageChannel orderChannel() {
    return new QueueChannel();
    }

    이것을 입력 채널로 사용할 때 컨슈머는 도착한 메시지 여부를 polling 해야 한다. 컨슈머가


    서비스 액티베이터인 경우는 다음과 같이 @ServiceActivator 애노테이션을 지정할 수 있다.

    @ServiceActivator(
    inputChannel = "orderChannel",
    poller = @Poller(fixedRate = "1000")
    )

    이 서비스 액티베이터는 orderChannel 이라는 이름의 채널로부터 매 1,000 밀리초 당 1번씩


    읽을 메시지가 있는지 확인한다.




    ■필터


    필터는 통합 파이프라인의 중간에 위치할 수 있으며, 플로우의 전 단계로부터 다음 단계로의


    메시지 전달을 허용 또는 불허한다. 예를 들어, 정수 값을 갖는 메시지가 numberChannel


    이라는 이름의 채널로 전달된다고 해보자. 이 경우 다음과 같이 @Filter 애노테이션이 


    지정된 필터를 선언할 수 있다.

    @Filter(
    inputChannel = "numberChannel",
    outputChannel = "evenNumberChannel"
    )
    public boolean evenNumberFilter(Integer number) {
    return number % 2 == 0;
    }

    또는 Java DSL 구성을 사용할 수도 있다.

    @Bean
    public IntegrationFlow evenNumberFlow(AtomicInteger integerSource) {
    return IntegrationFlows
    ...
    .<Integer>filter((p) -> p % 2 == 0)
    ...
    .get();
    }




    ■변환기


    변환기는 메시지 값의 변경이나 타입을 변환하는 일을 수행한다. 예를 들어, 정수 값을 


    포함하는 메시지가 numberChannel 이라는 이름의 채널로 입력되고, 이 숫자를 로마 


    숫자가 포함된 문자열로 변환한다고 해보자. 이 경우 다음과 같이 @Transformer 


    애노테이션을 지정하여 GenericTransformer 타입의 빈을 선언할 수 있다.

    @Bean
    @Transformer(
    inputChannel = "numberChannel",
    outputChannel = "romanNumberChannel"
    )
    public GenericTransformer<Integer, String> romanNumTransformer() {
    return RomanNumbers::toRoman;
    }

    @Transformer 애노테이션은 이 빈을 변환기 빈으로 지정한다. 즉, numberChannel로부터 


    Integer를 수신하고 static 메서드인 toRoman()을 사용해서 변환을 수행한다. 그리고 변환


    결과는 romanNumberChannel로 전송된다.


    Java DSL 구성에는 toRoman() 메서드의 메서드 참조를 인자로 전달하여 transform()을


    호출한다.

    @Bean
    public IntegrationFlow transformerFlow() {
    return IntegrationFlows
    ...
    .transform(RomanNumbers::toRoman)
    ...
    .get();
    }

    Java 구성과 Java DSL 구성 모두의 변환기 코드 예에서 메서드 참조를 사용했다. 그러나 


    변환기는 람다로 지정할 수도 있다. 또는 변환기가 별도의 자바 클래스로 만들만큼 


    복잡하다면, 빈으로 플로우 구성에 주입하고 이 빈의 참조를 transform()의 인자로 전달한다.

    @Bean
    public RomanNumberTransformer romanNumberTransformer() {
    return new RomanNumberTransformer();
    }
    @Bean
    public IntegrationFlow transformerFlow(RomanNumberTransformer romanNumberTransformer) {
    return IntegrationFlows
    ...
    .transform(romanNumberTransformer)
    ...
    .get();
    }

    여기서는 RomanNumberTransformer 타입의 빈을 선언한다. 이 빈은 스프링 통합의 


    Transformer나 GenericTransformer 인터페이스를 구현한 것이다. 이 빈은 


    transformerFlow()로 주입되고 통합 플로우를 정의할 때 transform()의 인자로 전달된다.




    ■라우터


    라우터는 전달 조건을 기반으로 통합 플로우 내부를 분기한다. (서로 다른 채널로 메시지를


    전달한다.) 예를 들어, 정수값을 전달하는 numberChannel이라는 채널이 있다고 하자.


    그리고 짝수 메시지는 evenChannel로 전달하고 홀수 메시지는 oddChannel로 전달한다.


    이러한 라우터를 통합 플로우에 생성할 때는 @Router가 지정된 AbstractMessageRouter 


    타입의 빈을 선언하면 된다.

    @Bean
    @Router(inputChannel = "numberChannel")
    public AbstractMessageRouter evenOddRouter() {
    return new AbstractMessageRouter() {
    @Override
    protected Collection<MessageChannel> determineTargetChannels(Message<?> message) {
    Integer number = (Integer) message.getPayload();
    if (number % 2 == 0) {
    return Collections.singleton(evenChannel());
    } else {
    return Collections.singleton(oddChannel());
    }
    }
    }
    }

    @Bean
    public MessageChannel evenChannel() {
    return new DirectChannel();
    }
    @Bean
    public MessageChannel oddChannel() {
    return new DirectChannel();
    }

    Java DSL 구성에서는 다음과 같이 route() 메서드를 호출하여 라우터를 선언한다.

    @Bean
    public IntegrationFlow numberRoutingFlow(AtomicInteger source) {
    return IntegrationFlows
    ...
    .<Integer, String > route(
    n -> n % 2 == 0 ? "EVEN" : "ODD",
    mapping -> mapping.subFlowMapping("EVEN", sf -> sf.<Integer, Integer>transform(n -> n * 10)
    .handle((i, j) -> {
    })
    ).subFlowMapping("ODD", sf -> sf.transform(RomanNumbers::toRoman)
    .handle((i, j) -> {
    }))
    )
    .get();

    AbstractMessageRouter를 따로 선언하고 이것을 route()의 인자로 전달하는 것도 


    가능하지만, 여기서는 메시지 페이로드가 홀수나 짝수 중 어느 것인지 결정하기 위해


    AbstractMessageRouter 대신 람다를 사용한다.




    ■분배기


    때로는 통합 플로우에서 하나의 메시지를 여러 개로 분할하여 독립적으로 처리할 필요가 


    생길 수 있다. 아래는 분배기를 유용하게 사용할 수 있는 두 가지 경우이다.


    • 메시지 페이로드가 컬렉션 데이터를 포함하고 있을 때, 컬렉션 데이터들의 종류별로 메시지를 분할하는 경우

    • 메시지 페이로드가 서로 연관되어 있는 정보(배달 정보, 주문 정보 등)를 포함하고 있을 때
      연관된 정보들을 서로 다른 타입의 메시지로 분할하는 경우


    하나의 메시지 페이로드를 두 개 이상의 서로 다른 타입 메시지로 분할할 때는 페이로드의


    각 부분을 추출하여 컬렉션의 요소들로 반환하는 POJO를 정의하면 된다.


    예를 들어, 주문 데이터를 전달하는 메시지는 대금 청구 정보와 주문 항목 리스트의 두 가지


    메시지로 분할할 수 있다. 다음의 OrderSplitter가 이런 일을 처리한다.

    public class OrderSplitter {
    public Collection<Object> splitOrderIntoParts(PurchaseOrder po) {
    ArrayList<Object> parts = new ArrayList<>();
    parts.add(po.getBillingInfo());
    parts.add(po.getLineItems());
    return parts;
    }
    }

    그 다음에 @Splitter 애노테이션을 지정하여 통합 플로우의 일부로 OrderSplitter 빈을


    선언할 수 있다.

    @Bean
    @Splitter(
    inputChannel = "poChannel",
    outputChannel = "splitOrderChannel"
    )
    public OrderSplitter orderSplitter() {
    return new OrderSplitter();
    }

    PayloadTypeRouter를 선언하여 대금 청구 정보와 주문 항목 정보를 각 정보에 적합한


    하위 플로우로 전달할 수 있다.

    @Bean
    @Router(inputChannel = "splitOrderChannel")
    public MessageRouter splitOrderRouter() {
    PayloadTypeRouter router = new PayloadTypeRouter();
    router.setChannelMapping(
    BillingInfo.class.getName(),
    "billingInfoChannel"
    );
    router.setChannelMapping(
    List.class.getName(),
    "lineItemsChannel"
    );
    return router;
    }

    여기서는 하나의 플로우가 두 개의 하위 플로우로 분할된다. BillingInfo 객체가 전달되는 


    플로우와, List<LineItem>이 전달되는 플로우다. 그러나 List<LineItem>을 처리하는 대신


    각 LineItem을 별도로 처리하고 싶다면 어떻게 해야 할까? 이때는 List<LineItem>을 다수의


    메시지로 분할하기 위해 @Splitter 애노테이션을 지정한 메서드를 작성하고 이 


    메서드에서는 처리된 LineItem이 저장된 컬렉션을 반환하면 된다.

    @Splitter(
    inputChannel = "lineItemsChannel",
    outputChannel = "lineItemChannel"
    )
    public List<LineItem> lineItemSplitter(List<LineItem> lineItems) {
    return lineItems;
    }

    이 경우, List<LineItem> 페이로드를 갖는 메시지가 lineItemsChannel에 도착하면 이 


    메시지는 lineItemSplitter()의 인자로 전달된다. 그리고 이 메서드는 분할된 lineItem들이 


    저장된 컬렉션을 반환하는데, 여기서는 이미 LineItem들이 저장된 컬렉션을 갖고 있으므로


    이것을 바로 반환한다. 이에 따라 이 컬렉션에 저장된 각 LineItem은 lineItemChannel로 


    전달된다.


    Java DSL을 사용하여 분배기/라우터 구성을 구현할 수도 있다.

    @Bean
    public IntegrationFlow routingFlow() {
    return IntegrationFlows
    ...
    .split(orderSplitter())
    .<Integer, String>route(
    p -> {
    if (p.getClass().isAssignableFrom(BillingInfo.class)) {
    return "BILLING_INFO";
    } else {
    return "LINE_ITEMS";
    }
    }, mapping -> mapping
    .subFlowMapping(
    "BILLING_INFO",
    sf -> sf.<BillingInfo>handle((billingInfo, h) -> {
    ...
    })
    )
    .subFlowMapping(
    "LINE_ITEMS",
    sf -> sf.split().<LineItem>handle((lineItem, h) -> {
    ...
    })
    )
    )
    .get();
    }




    ■서비스 액티베이터


    서비스 액티베이터는 입력 채널로부터 메시지를 수신하고, 이 메시지를 MessageHandler


    인터페이스를 구현한 클래스(빈)에 전달한다. 스프링 통합은 MessageHandler를 구현한 


    여러 클래스를 제공한다. 


    PayloadTypeRouter도 MessageHandler를 구현한 클래스다.


    한편 커스텀한 MessageHandler가 필요할 때가 있다. 다음은 서비스 액티베이터로 구성된 


    MessageHandler 빈을 선언하는 코드이다.

    @Bean
    @ServiceActivator(inputChannel = "someChannel")
    public MessageHandler sysoutHandler() {
    return message -> {
    System.out.println("Message payload :: " + message.getPayload());
    };
    }

    someChannel이라는 이름의 채널로부터 받은 메시지를 처리하는 서비스 액티베이터로 


    지정하기 위해 이 빈은 @ServiceActivator 애노테이션이 지정되었다. 여기서 


    MessageHandler 자체는 람다를 사용해서 구현했으며, 메시지를 받으면 이것의 payload를


    표준 출력 스트림으로 내보낸다.


    또는 받은 메시지의 데이터를 처리한 후 새로운 페이로드를 반환하는 서비스 액티베이터를


    선언할 수도 있다. 이 경우 GenericHandler를 구현해야 한다.

    @Bean
    @ServiceActivator(
    inputChannel = "orderChannel",
    outputChannel = "completeChannel"
    )
    public GenericHandler<Order> orderHandler(OrderRepository orderRepo) {
    return (payload, headers) -> {
    return orderRepo.save(payload);
    }
    }

    주문 메시지가 도착하면 orderRepo를 통해 저장하고, 저장된 Order 객체가 반환되면


    completeChannel이라는 이름의 출력 채널로 전달된다.


    GenericHandler는 메시지 payload는 물론이고, 위 예제에 등장하지는 않지만 메시지 


    헤더도 받는다. 그리고 Java DSL 구성으로도 서비스 액티베이터를 사용할 수 있다.


    이 경우, 플로우 정의에서 handle()의 인자로 MessageHandler나 GenericHandler를 


    전달하면 된다.

    public IntegrationFlow someFlow() {
    return IntegrationFlows
    ...
    .handle(msg -> {
    System.out.println("Message payload : " + msg.getPayload());
    })
    .get();
    }

    만일 서비스 액티베이터를 플로우의 제일 끝에 두지 않는다면 MessageHandler의 경우와


    유사하게 handle()에서 GenericHandler를 인자로 받을 수도 있다.

    public IntegrationFlow overFlow(OrderRepository orderRepo) {
    return IntegrationFlows
    ...
    .<Order>handle((payload, headers) => {
    return orderRepo.save(payload);
    })
    ...
    .get();
    }

    GenericHandler를 사용할 때는 람다나 메서드 참조에서 메시지 페이로드와 헤더를 


    매개변수로 받는다. 또한, GenericHandler를 플로우의 제일 끝에 사용한다면 null을 


    반환해야 한다. 그렇지 않으면 지정된 출력 채널이 없다는 에러가 발생할 것이다.




    ■게이트웨이


    게이트웨이는 애플리케이션이 통합 플로우로 데이터를 제출(submit)하고 선택적으로 


    플로우의 처리 결과인 응답을 받을 수 있는 수단이다. 스프링 통합에 구현된 게이트웨이는


    애플리케이션이 통합 플로우로 메시지를 전송하기 위해 호출할 수 있는 인터페이스로 


    구체화되어 있다. 이전에 살펴본 FileWriterGateway를 사용한 메시지 게이트웨이는 


    단방향 게이트웨이이며, 파일에 쓰기 위해 문자열을 인자로 받고 void를 반환하는 메서드를 


    갖고 있다. 양방향 게이트웨이의 작성도 어렵지 않으며, 이때는 게이트웨이 인터페이스를


    작성할 때 통합 플로우로 전송할 값을 메서드에서 반환해야 한다.


    예를 들어, 문자열을 받아서 모두 대문자로 변환하는 간단한 통합 플로우의 앞 쪽에 있는 


    게이트웨이를 생각해 보자. 이 게이트웨이 인터페이스는 다음과 같다.


    import org.springframework.integration.annotation.MessagingGateway;
    import org.springframework.stereotype.Component;

    @Component
    @MessagingGateway(
    defaultRequestChannel = "inChannel",
    defaultReplyChannel = "outChannel"
    )
    public interface UpperCaseGateway {
    String uppercase(String in);
    }

    사실은 이 인터페이스를 구현할 필요가 없다. 왜냐하면 지정된 채널을 통해 데이터를 


    전송하고 수신하는 구현체를 스프링 통합이 런타임 시에 자동으로 제공하기 때문이다.


    uppercase()가 호출되면 지정된 문자열이 통합 플로우의 inChannel로 전달된다. 그리고


    플로우가 어떻게 정의되고 무슨 일을 하는 지와 상관없이, 데이터가 outChannel로 도착하면


    uppercase() 로부터 반환된다. 이러한 대문자 변환 통합 플로우는 문자열을 대문자로 


    변환하기 위해 한 단계만으로 구성된 간단한 통합 플로우다. 이것을 Java DSL 구성으로 


    나타내면 다음과 같다.

    @Bean
    public IntegrationFlow uppercaseFlow() {
    return IntegrationFlows
    .from("inChannel")
    .<String, String> transform(String::toUpperCase)
    .channel("outChannel")
    .get();
    }

    메서드 참조로 정의된 변환기에 의해 메시지 페이로드가 변환된다. 그리고 결과 메시지는


    outChannel로 전달된다. 이것은 UpperCaseGateway 인터페이스의 응답 채널로 선언했던 


    채널이다.




    ■채널 어댑터


    채널 어댑터는 통합 플로우의 입구와 출구를 나타낸다. 데이터는 인바운드 채널 어댑터를


    통해 통합 플로우로 들어오고, 아웃바운드 채널 어댑터를 통해 통합 플로우에서 나간다.


    인바운드 채널 어댑터는 플로우에 지정된 데이터 소스에 따라 여러 가지 형태를 갖는다.


    예를 들어, 증가되는 숫자를 AtomicInteger로부터 플로우를 넣는 인바운드 채널 어댑터를


    선언할 수 있다.

    @Bean
    @InboundChannelAdapter(
    poller = @Poller(fixedRate = "1000"),
    channel = "numberChannel"
    )
    public MessageSource<Integer> numberSource(AtomicInteger source) {
    return () -> {
    return new GenericMessage<>(source.getAndIncrement());
    }
    }

    이 @Bean 메서드는 @InboundChannelAdapter가 인바운드 채널 어댑터를 지정하지만


    Java DSL의 경우는 from() 메서드가 인바운드 채널 어댑터의 일을 수행한다. Java 구성의


    인바운드 채널 어댑터와 유사한 채널 어댑터를 Java DSL로 정의하면 다음과 같다.

    @Bean
    public IntegrationFlow someFlow(AtomicInteger integerSource) {
    return IntegrationFlows
    .from(integerSource, "getAndIncrement",
    c -> c.poller(Pollers.fixedRate(1000)))
    ...
    .get();
    }

    종종 채널 어댑터는 스프링 통합의 여러 엔드포인트 모듈 중 하나에서 제공된다. 예를 들어


    지정된 디렉터리를 모니터링하여 해당 디렉터리에 저장하는 파일을 file-channel 이라는 


    이름의 채널에 메시지로 전달하는 인바운드 채널 어댑터가 필요하다고 해보자. 이 경우 


    스프링 통합 파일 엔드포인트 모듈의 FileReadingMessageSource를 사용하는 다음의 


    Java 구성으로 구현할 수 있다.

    @Bean
    @InboundChannelAdapter(
    poller = @Poller(fixedRate = "1000"),
    channel = "file-channel"
    )
    public MessageSource<File> fileReadingMessageSource() {
    FileReadingMessageSource sourceReader = new FileReadingMessageSource();
    sourceReader.setDirectory(new File(INPUT_DIR);
    sourceReader.setFilter(new SimplePatternFileListFilter(FILE_PATTERN)));
    return sourceReader
    }

    이것과 동일한 파일-읽기 인바운드 채널 어댑터를 Java DSL로 작성할 때는 Files 클래스의


    inboundAdapter()를 사용할 수 있다. 아웃바운드 채널 어댑터는 통합 플로우의 끝단이며


    최종 메시지를 애플리케이션이나 다른 시스템에 넘겨준다.

    @Bean
    public IntegrationFlow fileReaderFlow() {
    return IntegrationFlows
    .from(Files.inboundAdapter(new File(INPUT_DIR)))
    .patternFilter(FILE_PATTERN)
    .get();
    }

    메시지 핸들러로 구현되는 서비스 액티베이터는 아웃바운드 채널 어댑터로 자주 사용된다.


    특히, 데이터가 애플리케이션 자체에 전달될 필요가 있을 때 자주 사용된다.




    ■엔드포인트 모듈


    스프링 통합은 우리 나름의 채널 어댑터를 생성할 수 있게 해준다. 그러나 아래 표에 있는 


    것을 포함해서 다양한 외부 시스템과의 통합을 위해 채널 어댑터가 포함된 24개 이상의


    엔드 포인트 모듈(인바운드와 아웃바운드 모두)을 스프링 통합이 제공한다.


     모듈

     의존성 ID 

     AMQP

     spring-integration-amqp

     스프링 애플리케이션 이벤트

     spring-integration-event

     RSS와 Atom 

     spring-integration-feed

     파일 시스템 

     spring-integration-file

     FTP/FTPS

     spring-integration-ftp

     GemFire

     spring-integration-gemfire

     HTTP

     spring-integration-http

     JDBC

     spring-integration-jdbc

     JPA

     spring-integration-jpa

     이메일

     spring-integration-mail

     MongoDB

     spring-integration-mongodb
     MQTT spring-integration-mqtt

     Redis

     spring-integration-redis
     RMI spring-integration-rmi

     SFTP

     spring-integration-sftp

     STOMP spring-integration-stomp
     스트림 spring-integration-stream
     Syslog spring-integration-syslog

     TCP/UDP

     spring-integration-ip

     Twitter spring-integration-twitter
     웹 서비스

     spring-integration-ws

     WebFlux

     spring-integration-webflux

     WebSocket

     spring-integration-websocket

     XMPP 

     spring-integration-xmpp 

     ZooKeeper 

     spring-integration-zookeeper 


    각 엔드포인트 포듈은 채널 어댑터를 제공하며, 채널 어댑터는 Java 구성을 사용해 빈으로


    선언되거나, Java DSL 구성을 사용해 static 메서드로 참조할 수 있다. 다음 포스팅에서는


    이메일 엔드포인트 모듈을 타코 클라우드 애플리케이션에서 어떻게 사용할 수 있는지


    알아본다.

    댓글

Designed by Tistory.