Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- GPT-4's answer
- 리눅스
- python
- 코틀린
- 소프트웨어공학
- jpa
- Database
- 자바네트워크
- JVM
- 시스템
- write by GPT-4
- 자바암호
- 고전역학
- android
- 유닉스
- 인프라
- flet
- 역학
- 데이터베이스
- chatGPT's answer
- 자바
- Java
- write by chatGPT
- 파이썬
- oracle
- spring data jpa
- 웹 크롤링
- kotlin
- spring integration
- NIO
Archives
- Today
- Total
Akashic Records
Service Activator와 Message Handler - Service Activator를 사용한 비즈니스 로직 구현 본문
Spring Integration for Beginners
Service Activator와 Message Handler - Service Activator를 사용한 비즈니스 로직 구현
Andrew's Akashic Records 2025. 1. 2. 15:55728x90
2. Spring Integration 주요 컴포넌트 활용
2.1 Message Filter와 Router
2.2 Service Activator와 Message Handler
Service Activator를 사용한 비즈니스 로직 구현
1.1 Service Activator란?
Service Activator는 Spring Integration에서 메시지를 처리하기 위한 비즈니스 로직을 실행하는 엔드포인트(Endpoint)입니다.
- 목적: 메시지를 소비하고, 메시지의 Payload 또는 Header를 기반으로 비즈니스 로직을 실행.
- 사용 방식:
- POJO 기반의 메서드에 메시지를 전달.
- 비즈니스 로직 실행 후 결과를 반환하거나 메시지 흐름을 종료.
1.2 Service Activator의 주요 특징
- 메시지 처리:
- 메시지의 Payload와 Header를 읽어 비즈니스 로직을 수행.
- 처리 결과를 반환하여 다음 단계로 전달하거나 흐름을 종료.
- 유연성:
- POJO의 메서드를 호출하므로 기존 비즈니스 로직과 쉽게 통합 가능.
- 주요 어노테이션:
- @ServiceActivator: 메서드를 메시지 엔드포인트로 정의.
- XML 기반 설정에서도 <int:service-activator> 사용 가능.
1.3 Service Activator 기본 구성
- 입력 채널: 메시지가 전달되는 채널.
- Service Activator: 메시지를 소비하고 비즈니스 로직을 실행하는 메서드.
- 출력 채널(선택적): 처리 결과를 전달하는 채널.
1.4 예제: 주문 처리 시스템
요구사항
- 주문 메시지를 처리하여 상태를 업데이트.
- 처리 결과를 다른 채널로 전달.
1. Service Activator 설정
package kr.co.thekeytech.spring.eai.activator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.messaging.MessageChannel;
@Configuration
public class OrderService {
@Bean
public MessageChannel orderInputChannel() {
return new DirectChannel();
}
@Bean
public MessageChannel orderOutputChannel() {
return new DirectChannel();
}
private static final Logger logger = LoggerFactory.getLogger(OrderService.class);
@ServiceActivator(inputChannel = "orderInputChannel", outputChannel = "orderOutputChannel")
public String processOrder(String orderPayload) {
logger.info("OrderService Processed Order: {}", orderPayload);
return "OrderService UpdatedOrder, " + orderPayload;
}
}
설명:
- orderInputChannel: 주문 메시지를 전달받는 채널.
- orderOutputChannel: 처리 결과를 전달하는 채널.
- @ServiceActivator: processOrder 메서드를 Service Activator로 설정.
2. Gateway 설정
package kr.co.thekeytech.spring.eai.activator;
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.MessagingGateway;
@MessagingGateway
public interface OrderGateway {
@Gateway(requestChannel = "orderInputChannel")// inputChannel을 명시적으로 지정
void sendMessage(String message);
}
3. 메시지 전송
Service Activator 테스트 코드
package kr.co.thekeytech.spring.eai.activator;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest
class OrderFlowConfigTest {
@Autowired
private OrderGateway orderGateway;
@Autowired
private MessageChannel orderOutputChannel;
@Test
void testServiceActivator() {
QueueChannel outputQueue = new QueueChannel();
((DirectChannel) orderOutputChannel).subscribe(outputQueue::send);
// 주문 메시지 생성 및 전송
orderGateway.sendMessage("Order ID: 12345");
// 결과 출력
Message<?> outputMessage = outputQueue.receive(1000);
assertThat(outputMessage).isNotNull();
System.out.println("Final Service Activator Output: " + outputMessage.getPayload());
}
}
728x90
4. Integration Flow로 구현
orderFlow가 없어도 @ServiceActivator만으로 충분히 동작합니다. 그러나 다음과 같은 경우 orderFlow를 사용하는 것이 더 적합합니다:
- 복잡한 메시지 처리 로직(조건부 흐름, 데이터 변환, 다중 처리 등)이 필요한 경우.
- POJO 메서드 호출 외의 핸들러를 사용해야 하는 경우.
- 흐름을 명시적으로 정의하고자 하는 경우.
package kr.co.thekeytech.spring.eai.activator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.dsl.IntegrationFlow;
@Configuration
public class OrderFlowConfig {
private static final Logger logger = LoggerFactory.getLogger(OrderFlowConfig.class);
@Bean
public IntegrationFlow orderFlow(OrderService orderService) {
return IntegrationFlow.from("activator.order.input.channel")
.handle((payload, headers) -> {
logger.info("###########=> Before Handle OrderFlow: {}", payload);
return payload;
})
.transform(String.class, String::toUpperCase)
.handle(orderService, "processOrder") // Service Activator 호출
.handle((payload, headers) -> {
logger.info("###########=> After Handle OrderFlow: {}", payload);
return payload;
})
.channel("activator.order.output.channel")
.get();
}
}
설명:
- Service Activator에서 사용하는 InputChannel, OutputChannel 대신 별도의 채널 "activator.order.input.channel", "activator.order.output.channel"을 선언하여 사용합니다.
- 초기 로깅 Handle을 지정합니다.
- 메시지 변환(transform)으로 payload내용을 대문자로 치환합니다.
- Service Activator 메서드를 호출합니다.
- 후처리 로깅 Handle을 지정합니다.
- 출력 채널을 "activator.order.output.channel"을 지정합니다.
5. Gateway 설정
IntegrationFlow용 "sendMessageWithFlow" gateway을 설정합니다.
package kr.co.thekeytech.spring.eai.activator;
import org.springframework.integration.annotation.Gateway;
import org.springframework.integration.annotation.MessagingGateway;
@MessagingGateway
public interface OrderGateway {
@Gateway(requestChannel = "orderInputChannel")// inputChannel을 명시적으로 지정
void sendMessage(String message);
@Gateway(requestChannel = "activator.order.input.channel")// inputChannel을 명시적으로 지정
void sendMessageWithFlow(String message);
}
6. 메시지 전송
IntegrationFlow 테스트 코드
package kr.co.thekeytech.spring.eai.activator;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest
class OrderFlowConfigTest {
@Autowired
private OrderGateway orderGateway;
@Autowired
@Qualifier("activator.order.output.channel")
private MessageChannel orderOutputFlowChannel;
@Test
void testFlow() {
QueueChannel outputQueue = new QueueChannel();
((DirectChannel) orderOutputFlowChannel).subscribe(outputQueue::send);
// 주문 메시지 생성 및 전송
orderGateway.sendMessageWithFlow("Order ID: 67890");
// 결과 출력
Message<?> outputMessage = outputQueue.receive(1000);
assertThat(outputMessage).isNotNull();
System.out.println("Final Flow Output: " + outputMessage.getPayload());
}
}
728x90
'Spring Integration for Beginners' 카테고리의 다른 글
Splitter와 Aggregator - 메시지 분할(Split)과 집계(Aggregate) 이해 (0) | 2025.01.06 |
---|---|
Service Activator와 Message Handler - Custom Message Handler 작성 (2) | 2025.01.03 |
Message Filter와 Router - 동적 라우팅 구현 (0) | 2024.12.27 |
Message Filter와 Router - 조건에 따른 메시지 필터링 (2) | 2024.12.26 |
Spring Integration의 실용 사례 - 비동기 처리, email (0) | 2024.12.23 |
Comments