首页 > 其他分享 >spring 状态机demo

spring 状态机demo

时间:2023-10-17 09:13:44浏览次数:29  
标签:return String spring public 状态机 demo Order order id

spring 状态机demo
        <dependency>
            <groupId>org.springframework.statemachine</groupId>
            <artifactId>spring-statemachine-core</artifactId>
            <version>2.0.1.RELEASE</version>
        </dependency>
// 作为数据源

public class Data {
    public static List<Order> orderList = new ArrayList<>();


    public static void create(Order order) {
        orderList.add(order);
    }


    public static Order getById(String id) {
        return orderList.stream().filter(item -> Objects.equals(id, item.getId())).findFirst().orElse(null);
    }

    public static void update(Order order) {
        orderList.stream().filter(item -> Objects.equals(order.getId(), item.getId())).findFirst().ifPresent(
                item -> item.setStatus(order.getStatus()));
    }
}
// 订单实体
public class Order {
    private String id;
    private OrderStatus status;
}
/**
 * @author yangxj
 * @date 2023/10/16 10:37
 * 状态机配置
 */
@Configuration
@EnableStateMachine(name = "orderStatemachine")
public class OrderStatemachineConfig extends StateMachineConfigurerAdapter<OrderStatus,OrderStatusChangeEvent> {


    @Bean(name = "stateMachinePersister")
    public StateMachinePersister<OrderStatus, OrderStatusChangeEvent, String> getPersister() {
        return new DefaultStateMachinePersister<>(new StateMachinePersist<OrderStatus, OrderStatusChangeEvent, String>() {
            @Override
            public void write(StateMachineContext<OrderStatus, OrderStatusChangeEvent> context, String contextObj) throws Exception {
                map.put(contextObj, context);
            }

            @Override
            public StateMachineContext<OrderStatus, OrderStatusChangeEvent> read(String contextObj) throws Exception {
                return map.get(contextObj);
            }
            Map<String, StateMachineContext<OrderStatus, OrderStatusChangeEvent>> map = new HashMap<>();
        });
    }
    /**
     * 配置状态
     */
    @Override
    public void configure(StateMachineStateConfigurer<OrderStatus, OrderStatusChangeEvent> states) throws Exception {
        states.withStates()
                .initial(OrderStatus.WAIT_PAYMENT)
                .states(EnumSet.allOf(OrderStatus.class));
    }

    /**
     * 配置转换事件
     */
    @Override
    public void configure(StateMachineTransitionConfigurer<OrderStatus, OrderStatusChangeEvent> transitions) throws Exception {
        transitions
                //支付事件:待支付-》待发货
                .withExternal().source(OrderStatus.WAIT_PAYMENT).target(OrderStatus.WAIT_DELIVER).event(OrderStatusChangeEvent.PAYED_EVENT)
                .and()
                //发货事件:待发货-》待收货
                .withExternal().source(OrderStatus.WAIT_DELIVER).target(OrderStatus.WAIT_RECEIVE).event(OrderStatusChangeEvent.DELIVERED_EVENT)
                .and()
                //收货事件:待收货-》已完成
                .withExternal().source(OrderStatus.WAIT_RECEIVE).target(OrderStatus.FINISH).event(OrderStatusChangeEvent.RECEIVED_EVENT);
    }
}
// 订单状态枚举
public enum OrderStatus {
    WAIT_PAYMENT(1, "待支付"),
    WAIT_DELIVER(2, "待发货"),
    WAIT_RECEIVE(3, "待收货"),
    FINISH(4, "已完成");

    private final Integer key;
    private final String  name;

    OrderStatus(Integer key, String name) {
        this.key = key;
        this.name = name;
    }
    public Integer getKey() {
        return key;
    }
    public String getName() {
        return name;
    }
}

// 订单状态改变事件
public enum OrderStatusChangeEvent {
    // 支付,发货,确认收货
    PAYED_EVENT,
    DELIVERED_EVENT,
    RECEIVED_EVENT;
}
//  事件监听处理

@WithStateMachine(name = "orderStatemachine")
@Slf4j
public class OrderStatusChangeEventListener {

    @OnTransition(source = "WAIT_PAYMENT", target = "WAIT_DELIVER")
    public boolean payTransition(Message<OrderStatusChangeEvent> message) {
        Order order = (Order) message.getHeaders().get("order");
        log.info("支付,状态机反馈信息:{}", message.getHeaders());
        //更新订单
        order.setStatus(OrderStatus.WAIT_DELIVER);
        Data.update(order);
        return true;
    }

    @OnTransition(source = "WAIT_DELIVER", target = "WAIT_RECEIVE")
    public boolean deliverTransition(Message<OrderStatusChangeEvent> message) {
        Order order = (Order) message.getHeaders().get("order");
        log.info("发货,状态机反馈信息:{}", message.getHeaders());
        //更新订单
        order.setStatus(OrderStatus.WAIT_RECEIVE);
        Data.update(order);
        return true;
    }

    @OnTransition(source = "WAIT_RECEIVE", target = "FINISH")
    public boolean receiveTransition(Message<OrderStatusChangeEvent> message) {
        Order order = (Order) message.getHeaders().get("order");
        log.info("确认收货,状态机反馈信息:{}", message.getHeaders());
        //更新订单
        order.setStatus(OrderStatus.FINISH);
        Data.update(order);
        return true;
    }
}
@RestController
@RequestMapping("/order")
public class OrderController {  
    @Resource
    private OrderService orderService;  
    /**  
     * 根据id查询订单  
     *  
     * @return  
     */  
    @RequestMapping("/getById")  
    public Order getById(@RequestParam("id") String  id) {
        //根据id查询订单  
        Order order = orderService.getById(id);  
        return order;  
    }  
    /**  
     * 创建订单  
     *  
     * @return  
     */  
    @RequestMapping("/create")  
    public String create(@RequestBody Order order) {
        //创建订单  
        orderService.create(order);  
        return "sucess";  
    }
    /**  
     * 对订单进行支付  
     *  
     * @param id  
     * @return  
     */  
    @RequestMapping("/pay")  
    public String pay(@RequestParam("id") String id) {
        //对订单进行支付  
        orderService.pay(id);  
        return "success";  
    }  
  
    /**  
     * 对订单进行发货  
     *  
     * @param id  
     * @return  
     */  
    @RequestMapping("/deliver")  
    public String deliver(@RequestParam("id") String id) {
        //对订单进行确认收货  
        orderService.deliver(id);  
        return "success";  
    }  
    /**  
     * 对订单进行确认收货  
     *  
     * @param id  
     * @return  
     */  
    @RequestMapping("/receive")  
    public String receive(@RequestParam("id") String id) {
        //对订单进行确认收货  
        orderService.receive(id);  
        return "success";  
    }  
}  



/**
 * @author yangxj
 * @date 2023/10/16 10:55
 */
@Slf4j
@Service
public class OrderService {
    @Resource
    StateMachine<OrderStatus, OrderStatusChangeEvent> orderStateMachine;
    @Resource
    StateMachinePersister<OrderStatus, OrderStatusChangeEvent, String> stateMachinePersister;

    /**
     * 创建订单
     *
     * @param order
     * @return
     */
    public Order create(Order order) {
        order.setStatus(OrderStatus.WAIT_PAYMENT);
        Data.create(order);
        return order;
    }

    /**
     * 对订单进行支付
     *
     * @param id
     * @return
     */
    public Order pay(String id) {
        log.info("线程名称:{},尝试支付,订单号:{}", Thread.currentThread().getName(), id);
        Order order = Data.getById(id);
        if (!sendEvent(OrderStatusChangeEvent.PAYED_EVENT, order)) {
            log.error("线程名称:{},支付失败, 状态异常,订单信息:{}", Thread.currentThread().getName(), order);
            throw new RuntimeException("支付失败, 订单状态异常");
        }
        return order;
    }

    /**
     * 对订单进行发货
     *
     * @param id
     * @return
     */
    public Order deliver(String id) {
        Order order = Data.getById(id);
        log.info("线程名称:{},尝试发货,订单号:{}", Thread.currentThread().getName(), id);
        if (!sendEvent(OrderStatusChangeEvent.DELIVERED_EVENT, order)) {
            log.error("线程名称:{},发货失败, 状态异常,订单信息:{}", Thread.currentThread().getName(), order);
            throw new RuntimeException("发货失败, 订单状态异常");
        }
        return order;
    }

    /**
     * 对订单进行确认收货
     *
     * @param id
     * @return
     */
    public Order receive(String id) {
        Order order = Data.getById(id);
        log.info("线程名称:{},尝试收货,订单号:{}", Thread.currentThread().getName(), id);
        if (!sendEvent(OrderStatusChangeEvent.RECEIVED_EVENT, order)) {
            log.error("线程名称:{},收货失败, 状态异常,订单信息:{}", Thread.currentThread().getName(), order);
            throw new RuntimeException("收货失败, 订单状态异常");
        }
        return order;
    }

    /**
     * 发送订单状态转换事件
     * synchronized修饰保证这个方法是线程安全的
     *
     * @param changeEvent
     * @param order
     * @return
     */
    private synchronized boolean sendEvent(OrderStatusChangeEvent changeEvent, Order order) {
        boolean result = false;
        try {
            // 状态机重置
            stateMachinePersister.restore(orderStateMachine, order.getId());
            Message<OrderStatusChangeEvent> message = MessageBuilder.withPayload(changeEvent).setHeader("order", order).build();
            result = orderStateMachine.sendEvent(message);
            // 状态机持久化
            stateMachinePersister.persist(orderStateMachine, order.getId());
        } catch (Exception e) {
            log.error("订单操作失败, order: {}", order, e);
        } finally {
            orderStateMachine.stop();
        }
        return result;
    }

    public Order getById(String id) {
        return Data.getById(id);
    }
}

 

标签:return,String,spring,public,状态机,demo,Order,order,id
From: https://www.cnblogs.com/yangxijun/p/17768868.html

相关文章

  • scanner Demo04
    packagecom.chen.scanner;importjava.util.Scanner;publicclassDemo04{publicstaticvoidmain(String[]args){Scannerscanner=newScanner(System.in);//从键盘接收inti=0;floatf=0.0f;System.out.println(&quo......
  • scanner Demo05
    packagecom.chen.scanner;importjava.util.Scanner;publicclassDemo05{publicstaticvoidmain(String[]args){//我们可以输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果;Scannerscanner=newSc......
  • C语言线性表 demo
    typedefintPosition;typedefstructLNode*List;structLNode{ElementTypeData[MAXSIZE];PositionLast;};/*初始化*/ListMakeEmpty(){ListL;L=(List)malloc(sizeof(structLNode));L->Last=-1;returnL;}/*查找*/#d......
  • Spring Framework
    一、IOC/DIIoC(InversionofControl)控制反转DI(dependencyinjection)依赖注入IoC/DI指的是一个过程:对象的创建仅仅通过Spring容器负责,Spring容器可以通过对象的构造方法或工厂方法进行实例化对象。在创建对象过程中,如果对象需要依赖其他对象,也可以直接在Spring容器中注入到......
  • Spring Boot 2.0 @ModelAttribute
    SpringBoot2.0中的注解@ModelAttribute有什么作用呢?通常情况下,我们会将@ModelAttribute注解放置在Controller中的某个方法上,那么,如果您在请求这个Controller中定义的URI时,会首先调用这个被注解的方法,并将该方法的结果作为Model的属性,然后才会调用对应URI的处理......
  • SpringCloud专题面试
    1.微服务架构优缺点1)单体应用开发的效率比较低,由于代码量大,项目启动缓慢,部署麻烦,后期难以维护。2)服务拆分分为多个小应用,提高了开发效率,降低了代码的耦合程度,不同的服务可以采用不同的语言,提高了灵活性;小的改动进行快捷部署,方便维护。3)拆分的依据原则就是高内聚低耦合,每个服......
  • java -jar命令及SpringBoot通过java -jav启动项目的过程
    本篇文章将为大家讲述关于SpringBoot项目工程完成后,是如何通过java-jar命令来启动的,以及介绍java-jar命令的详细内容,对SpringBootjava-jav启动过程感兴趣的朋友跟随小编一起看看吧本篇文章将为大家讲述关于SpringBoot项目工程完成后,是如何通过java-jar命令来启动的......
  • java-springboot和servlet的项目搭建
    1.404->启动tomcat->tomcat闪退->配置jre全局环境,重启电脑->8080端口被占用->下载太多tomcat->重新配置->还是被占用->命令行找netstat-ano|findstr80得到PID,在任务管理器找到(用PID排序会更好找)是一个java.exe,结束进程。->成功运行2.入口类3.mysql命令不生效->因为没加分号(我......
  • SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数
    最近在研究这块的信息,记录下一些大神的文章:SpringBoot最大连接数及最大并发数是多少???https://blog.csdn.net/weixin_44421461/article/details/132486085SpringBoot+内置Tomcat配置,参数调优,最大并发量,最大连接数https://blog.csdn.net/myyhtw/article/details/129069586Sprin......
  • Nacos源码 (7) Nacos与Spring
    SpringCloud工程可以使用Nacos作为注册中心和配置中心,配置和使用非常简单,本文将简单介绍使用方式,并分析其实现方式。SpringCloud工程集成NacosSpringCloud工程使用Nacos非常简单,只需要引入依赖、编写配置参数、在启动类上添加注解即可。引入依赖<dependencyManagement><dep......