一种无状态的状态机-cola
<!-- 状态机相关引用 -->
<dependency>
<groupId>com.alibaba.cola</groupId>
<artifactId>cola-component-statemachine</artifactId>
<version>4.0.1</version>
<type>jar</type>
</dependency>
状态机的初始化配置
支持状态流转的枚举类
public enum States {
/**
* 申请
*/
APPLY(1, "申请"),
/**
* 初审
*/
FIRST_TRIAL(2, "初审"),
/**
* 终审
*/
FINAL_JUDGEMENT(3, "终审"),
/**
* 移出
*/
REMOVE(4, "移出");
States(Integer value, String name) {
this.value = value;
this.name = name;
}
private final Integer value;
private final String name;
public Integer getValue() {
return value;
}
public String getName() {
return name;
}
}
事件,支撑枚举类做流程流转
public enum Events {
/**
* 保存申请
*/
SAVE_APPLICATION,
/**
* 提交申请
*/
SUBMIT_APPLICATION,
/**
* 审批通过
*/
AUDIT_AGREE,
/**
* 审批退回
*/
AUDIT_REJECT;
}
状态机的id
public class BusinessConstant {
//发起审批的流程状态机
public static final String APPLY_STATION_MACHINE_START = "applyStationMachineStart";
}
值传递
/**
* 流程之后数据传递的上下文
*
* @author dlf
* @date 2023/4/20 17:50
*/
@Data
public class Context {
String operator = "flw";
String entityId = "1885573359";
String name = "dlf";
private UserDo userDo;
}
这里是配置了一个流程,后续可以根据自己的需要配置多个流程
**
* 状态机的初始化配置
*
* @author dlf
* @date 2023/4/20 17:41
*/
@Configuration
public class StatemachineConfig {
@Resource
private UserService userService;
/* @PostConstruct
public void init() {
testExternalTransitionNormalApply();
}*/
/**
* State:状态
* Event:事件,状态由事件触发,引起变化
* Transition:流转,表示从一个状态到另一个状态
* External Transition:外部流转,两个不同状态之间的流转
* Internal Transition:内部流转,同一个状态之间的流转
* Condition:条件,表示是否允许到达某个状态
* Action:动作,到达某个状态之后,可以做什么
* StateMachine:状态机
*/
@Bean
public StateMachineBuilder<States, Events, Context> testExternalTransitionNormalApply() {
// 第一步:生成一个状态机builder
StateMachineBuilder<States, Events, Context> builder = StateMachineBuilderFactory.create();
// 第二步:设置一个外部状态转移类型的builder,并设置from\to\on\when\perform
builder.externalTransition() // 外部状态流转
.from(States.APPLY) // 起始状态:申请
.to(States.FIRST_TRIAL) // 目的状态:初审
.on(Events.SUBMIT_APPLICATION) // 事件:提交申请
//.when(checkCondition()) // 流转需要校验的条件,校验不通过不会进行doAction
.perform(userService.action()); // 执行流转操作 这个action 我们可以按自己所需修改,比如这种Action<R,T> service的方法Service::method
// 第三步:设置状态机的id和ready,并在StateMachineFactory中的stateMachineMap进行注册
builder.build(BusinessConstant.APPLY_STATION_MACHINE_START);
/* // 第四步:触发状态机
StateMachine<States, Events, Context> stateMachine = StateMachineFactory.get(BusinessConstant.APPLY_STATION_MACHINE_START);
stateMachine.showStateMachine();
// 通过状态机执行 待审核状态执行审核操作,
States target1 = stateMachine.fireEvent(States.APPLY, Events.SUBMIT_APPLICATION, new Context());*/
return builder;
}
}
示例代码
public interface UserService {
public int addOne(UserDo userDo);
public Action<States, Events, Context> action();
public String actionSys();
}
示例代码
/**
* @author dlf
* @date 2023/4/20 18:05
*/
@Data
public class UserDo {
private String userName;
private String passWord;
private String process;
}
示例代码演示状态机得使用
/**
* @author dlf
* @date 2023/4/20 18:15
*/
@Service
@Slf4j
public class UserServiceImpl implements UserService {
@Resource
private UserDao userDao;
@Override
public int addOne(UserDo userDo) {
return userDao.add(userDo);
}
@Override
public Action<States, Events, Context> action() {
//审批提交的具体流程
return (from, to, event, ctx) -> {
UserDo turnsForm = ctx.getUserDo();
log.info("原来的状态为:"+turnsForm.getProcess());
System.err.println("UserDo:"+userDao);
turnsForm.setProcess("待审批");
log.info("目标状态为:"+turnsForm.getProcess());
};
}
@Override
public String actionSys() {
Context context = new Context();
UserDo userDo = new UserDo();
userDo.setUserName("machineTest");
userDo.setPassWord("dlf123");
userDo.setProcess("发起申请....");
StateMachine<States, Events, Context> stateMachine = StateMachineFactory.get(BusinessConstant.APPLY_STATION_MACHINE_START);
stateMachine.showStateMachine();
stateMachine.fireEvent(States.APPLY, Events.SAVE_APPLICATION, context);
StateMachine<States, Events, Context> contextStateMachine = StateMachineFactory.get(BusinessConstant.APPLY_STATION_MACHINE_START);
return userDo.getProcess();
}
测试流程
/**
* @author dlf
* @date 2023/4/21 15:40
*/
@RestController
@Slf4j
@RequestMapping("/test")
public class UserController {
@Value("${server.port}")
private String serverPort;
@Resource
public UserService userService;
@GetMapping("/testMachione")
public String testMachine() {
return userService.actionSys();
}
}