티스토리 뷰
1. 개요
EnumStateMachineConfigurerAdapter는 Spring State Machine(Spring Statemachine)에서 상태(State) 및 이벤트(Event)를 Enum으로 정의할 때 사용되는 설정 클래스입니다.
Spring Statemachine은 상태 기반 로직을 구현할 수 있도록 지원하는 프레임워크로, 워크플로우 관리, 주문 처리 시스템, 권한 승인 흐름 등에서 유용하게 활용될 수 있습니다.
2. Spring State Machine 개념
Spring Statemachine은 유한 상태 머신(Finite-State Machine, FSM)을 기반으로 동작합니다.
다음 요소로 구성됩니다.
- 상태(State): 객체의 특정 상태를 의미하며, Enum을 활용하여 정의할 수 있습니다.
- 이벤트(Event): 상태를 변화시키는 트리거(trigger) 역할을 합니다.
- 전이(Transition): 한 상태에서 다른 상태로 변화하는 과정입니다.
- 가드(Guard): 상태 전이가 가능한지를 검사하는 조건입니다.
- 액션(Action): 상태 전이가 발생할 때 실행되는 동작입니다.
3. EnumStateMachineConfigurerAdapter 사용 방법
3.1. 의존성 추가
Spring Statemachine을 사용하려면 Maven 또는 Gradle에서 의존성을 추가해야 합니다.
Maven 설정
<dependency>
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-core</artifactId>
<version>3.2.0</version>
</dependency>
Gradle 설정
implementation 'org.springframework.statemachine:spring-statemachine-core:3.2.0'
3.2. 상태(Enum) 및 이벤트(Enum) 정의
Spring Statemachine에서는 상태와 이벤트를 Enum으로 정의합니다.
public enum OrderState {
NEW, PROCESSING, SHIPPED, DELIVERED, CANCELLED
}
public enum OrderEvent {
PROCESS_ORDER, SHIP_ORDER, DELIVER_ORDER, CANCEL_ORDER
}
- OrderState는 주문(Order)의 상태를 나타내는 Enum입니다.
- OrderEvent는 상태 전이를 발생시키는 이벤트입니다.
3.3. EnumStateMachineConfigurerAdapter 구현
EnumStateMachineConfigurerAdapter를 상속하여 상태 머신을 구성할 수 있습니다.
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.listener.StateMachineListenerAdapter;
import org.springframework.statemachine.state.State;
import java.util.EnumSet;
@Configuration
@EnableStateMachine
public class OrderStateMachineConfig extends EnumStateMachineConfigurerAdapter<OrderState, OrderEvent> {
@Override
public void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception {
states
.withStates()
.initial(OrderState.NEW) // 초기 상태 설정
.states(EnumSet.allOf(OrderState.class)); // 모든 상태 등록
}
@Override
public void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception {
transitions
.withExternal()
.source(OrderState.NEW).target(OrderState.PROCESSING).event(OrderEvent.PROCESS_ORDER)
.and()
.withExternal()
.source(OrderState.PROCESSING).target(OrderState.SHIPPED).event(OrderEvent.SHIP_ORDER)
.and()
.withExternal()
.source(OrderState.SHIPPED).target(OrderState.DELIVERED).event(OrderEvent.DELIVER_ORDER)
.and()
.withExternal()
.source(OrderState.NEW).target(OrderState.CANCELLED).event(OrderEvent.CANCEL_ORDER);
}
@Override
public void configure(StateMachineConfigurationConfigurer<OrderState, OrderEvent> config) throws Exception {
config
.withConfiguration()
.listener(new StateMachineListenerAdapter<>() {
@Override
public void stateChanged(State<OrderState, OrderEvent> from, State<OrderState, OrderEvent> to) {
System.out.println("상태 변경: " + (from != null ? from.getId() : "NONE") + " → " + to.getId());
}
});
}
}
설정 설명
- @EnableStateMachine
- Spring State Machine을 활성화하는 애노테이션입니다.
- configure(StateMachineStateConfigurer states)
- 가능한 모든 상태를 정의합니다.
- initial(OrderState.NEW): 최초 상태를 NEW로 설정합니다.
- configure(StateMachineTransitionConfigurer transitions)
- 상태 전이를 정의합니다.
- source(현재 상태).target(다음 상태).event(이벤트) 형태로 설정됩니다.
- configure(StateMachineConfigurationConfigurer config)
- 상태 머신의 설정을 추가합니다.
- StateMachineListenerAdapter를 통해 상태 변경 시 로그를 출력합니다.
3.4. 상태 머신을 사용하여 상태 전이 처리
설정한 상태 머신을 사용하려면 StateMachine 객체를 주입받아 실행할 수 있습니다.
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.statemachine.StateMachine;
import org.springframework.stereotype.Service;
@Service
public class OrderService {
@Autowired
private StateMachine<OrderState, OrderEvent> stateMachine;
public void processOrder() {
stateMachine.sendEvent(OrderEvent.PROCESS_ORDER);
}
public void shipOrder() {
stateMachine.sendEvent(OrderEvent.SHIP_ORDER);
}
public void deliverOrder() {
stateMachine.sendEvent(OrderEvent.DELIVER_ORDER);
}
public void cancelOrder() {
stateMachine.sendEvent(OrderEvent.CANCEL_ORDER);
}
}
설명
- sendEvent(OrderEvent.PROCESS_ORDER)를 호출하면 NEW → PROCESSING 상태로 전환됩니다.
- 같은 방식으로 shipOrder(), deliverOrder(), cancelOrder()를 호출하여 상태를 변경할 수 있습니다.
4. 주요 기능
기능 설명
초기 상태 설정 | initial(OrderState.NEW)을 사용하여 초기 상태를 정의할 수 있습니다. |
상태 전이(Transition) 설정 | transitions.withExternal()을 사용하여 상태 전이를 정의합니다. |
이벤트 기반 상태 변화 | stateMachine.sendEvent(event)를 호출하여 상태를 변경할 수 있습니다. |
리스너(Listener) 추가 가능 | 상태 변화 감지를 위해 StateMachineListenerAdapter를 사용할 수 있습니다. |
가드(Guard) 조건 추가 가능 | 특정 조건이 충족될 때만 상태 전이를 허용할 수 있습니다. |
5. 장점
- 상태 기반 로직을 쉽게 관리
- EnumStateMachineConfigurerAdapter를 사용하면 복잡한 상태 전이 로직을 Enum과 설정 파일을 통해 쉽게 정의할 수 있습니다.
- Spring과 통합이 용이함
- @EnableStateMachine을 통해 Spring 환경에서 손쉽게 상태 머신을 활용할 수 있습니다.
- 이벤트 기반 워크플로우 관리 가능
- sendEvent(event) 메서드를 통해 다양한 이벤트에 따른 상태 변화를 쉽게 구현할 수 있습니다.
- 리스너를 통한 상태 변화 추적 가능
- StateMachineListenerAdapter를 활용하면 상태 변화 시 로깅이나 추가 로직을 실행할 수 있습니다.
6. 결론
- EnumStateMachineConfigurerAdapter는 Spring Statemachine을 사용할 때 상태와 이벤트를 Enum으로 정의하고 설정하는 역할을 합니다.
- configure() 메서드를 통해 초기 상태, 상태 전이, 리스너 등을 설정할 수 있으며, sendEvent(event)를 통해 상태를 변경할 수 있습니다.
- 워크플로우 관리, 주문 처리 시스템, 승인 시스템 등 상태 기반 프로세스에서 매우 유용하게 활용할 수 있습니다.
- Spring Boot 환경에서 @EnableStateMachine을 적용하면 손쉽게 상태 기반 애플리케이션을 개발할 수 있습니다.