Khoi Nguyen
Khoi Nguyen

Reputation: 1092

How to use Spring state machine for an Order object

I'm trying to use Spring State Machine in my project, because there is an object is Order with several state

That object could be implement as following

public class Order {
  private String id;
  private Customer customer;
  private OrderState state;
// Some other fields with getter and setter
}

and I introduced OrderService, get order from DB, set some information including OrderState, and then save to DB.

However I don't know how to apply Spring state machine into this one, is it too complex to use with simple purpose like that?

Upvotes: 7

Views: 7958

Answers (1)

mirmdasif
mirmdasif

Reputation: 6354

Define your states

public enum OrederStates {
   NEW, PAID, PACKAGED; // etc
}

Then define your events

public enum OrderEvents {
    PAYMENT, PACK, DELIVER; // etc 
}

Then declare your event listeners

@WithStateMachine
public class OrderEventHandler {
    @Autowired
    OrderService orderService;

    @OnTransition(src= "NEW",target = "PAID")
    handlePayment() {
       // Your code orderService.*
       // ..   
    }
    // Other handlers
}

Now configure your application to to use state machine

@Configuration
@EnableStateMachine
static class Config1 extends EnumStateMachineConfigurerAdapter<States, Events> {

    @Override
    public void configure(StateMachineStateConfigurer<States, Events> states)
            throws Exception {
        states
            .withStates()
                .initial(OrderStates.NEW)
                .states(EnumSet.allOf(OrderStates.class));
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
            throws Exception {
        transitions
            .withExternal()
                .source(OrderStates.NEW).target(OrderStates.PAID)
                .event(OrderEvents.PAYMENT)
                .and()
            .withExternal()
                .source(OrderStates.PAID).target(OrderStates.PACKED)
                .event(OrderEvents.PACK);
    }
}

And finally use it in your Application/Controller

public class MyApp {

    @Autowired
    StateMachine<States, Events> stateMachine;

    void doSignals() {
        stateMachine.start();
        stateMachine.sendEvent(OrderEvents.PAYMENT);
        stateMachine.sendEvent(Events.PACK);
    }
 }

Use this guide for getting started with state machine and this referce to learn more.

Upvotes: 8

Related Questions