Spring Boot 为Sping Boot 应用程序实现状态管理

z9smfwbn  于 2023-08-04  发布在  Spring
关注(0)|答案(2)|浏览(135)

我正在做一个Sping Boot 应用程序,我需要实现一个如下格式的状态转换表,其中action和condition的组合决定了实体从一个状态到另一个状态的转换:

From State| To State|   User Action      | Condition
----------------------------------------------------------------
    S0    |   S1    | Create a record    |         
-----------------------------------------------------------------
    S1    |   S1    | Update a record    |         
 -----------------------------------------------------------------
    S1    |   S1    | Run validation     |
 -----------------------------------------------------------------
    S1    |   S2    | Mark state as S2   |  Record is valid

字符串
在这个应用程序中,已经有CreateUpdateRunning Validation的API。
根据要求,状态机应该是可配置的,以便可以添加任何新状态/可以删除现有状态,以及可以通过 Jmeter 板针对给定转换更改操作和条件。
为了满足这个要求,我考虑将StateActionConditionStateTransition作为单独的实体,如下所示:
行动实体:

@Entity
 @Table(name = "action")
 public class Action implements Serializable {
     @Id
     private String id;

     @Column(name = "action_type")
     @Enumerated(EnumType.STRING)
     private ActionType actionType;

     @Column(name = "action_description")
     private String actionDescription;
 }


操作类型枚举:

Enum ActionType {
   CREATE_RECORD, UPDATE_RECORD, RUN_VALIDATION;
}


国家实体:

@Entity
 @Table(name = "state")
 public class State implements Serializable {
     @Id
     private String id;

     @Column(name = "name")
     private String name;
 }


条件实体(无法理解如何执行此操作)

@Entity
 @Table(name = "condition")
 public class Condition implements Serializable {
     @Id
     private String id;

     @Column(name = "description")
     private String description;

     ... CANNOT UNDERSTAND WHAT ELSE SHOULD I PUT HERE
 }


状态过渡实体如下:

@Entity
 @Table(name = "state_transition")
 public class State implements Serializable {
     @Id
     private String id;

     @Column(name = "from_state")
     private String fromStateId;

     @Column(name = "to_state")
     private String toStateId;

     @Column(name = "action_id")
     private String actionId;

     @Column(name = "condition_id")
     private String conditionId;
 }


基本上,通过当前状态、动作和条件的组合,我应该能够从状态转换表中找出下一个状态。
但我被以下事情卡住了:
1.我应该如何执行用户操作?正如我之前提到的,我上面指定的一些操作已经作为API存在于应用程序中。基本上,我无法理解如何将我想实现的用户操作实体与现有流绑定在一起。
1.我应该如何将条件作为一个实体来实现?Condition基本上是一个表达式,其计算结果为True/False。我没有得到任何线索,因为,我怎么能捕捉到这个作为一个实体。
有没有人能就这一点给予一些建议?- 谢谢-谢谢

idfiyjo8

idfiyjo81#

我看不出引入所有这些实体的理由。动作似乎是静态的,即。你是在代码中定义可能的操作,那么为什么要为此创建一个实体呢?Condition只是Transition实体中包含表达式的字段。我也不认为你需要有一个专门的实体,但这可能是有争议的。总的来说,我建议您将状态机序列化为JSON,因为无论如何都要读取整个状态机。因此,除非您希望能够查询或引用该定义中的专用元素(引用完整性),否则不要将其建模为表。所以要么

@Entity
 @Table(name = "state_transition")
 public class StateTransition implements Serializable {
     @Id
     private String id;

     @Column(name = "from_state")
     private String fromState;

     @Column(name = "to_state")
     private String toState;

     @Column(name = "action")
     private ActionType action;

     @Column(name = "condition")
     private String condition;
 }

字符串
或者是

@Entity
 @Table(name = "state_machine")
 public class StateMachine implements Serializable {
     @Id
     private String id;

     @Column(name = "definition")
     private String definition;

 }


然后,您可以反序列化该定义,甚至可以在AttributeConverter中将其反序列化为适合您需要的任何模型。

lp0sw83n

lp0sw83n2#

我认为你在过去找到了答案,但对于其他人可能有同样的问题,Spring Statemachine可以很好地解决这个问题。并通过this学习基本功能。如果我们有一个这样的工作流程:


的数据
对于定义第一个和最后一个状态以及中间状态,请使用以下命令:

states
.withStates()
.initial("start-state")
.end("end-state")
.states(new HashSet<String>(Arrays.asList("state-one", "state-two")));

字符串
每个状态可能有一些方法可以调用,您可以通过以下方式定义:

transitions.withExternal()
 .source("start-state").target("state-one").event("start").and()
 .withExternal()
 .source("state-one").target("state-two").event("event2").and()
 .withExternal()
 .source("state-two").target("end-state").event("end");

相关问题