如何为库中提供的 Spring 状态机实现依赖于实现的转换守卫?

How to achieve implementation dependend transition guards for a Spring statemachine provided in a library?

我在库中提供了一个具有基本程序状态的 Spring 状态机 作为不同实现的基础。 添加自定义转换动作 取决于当前使用基本状态机的实现,似乎很容易 因为提供了 transition annotations

现在我想对守卫做一些类似的事情,即根据使用基本状态机的实现中最近的使用场景提供一个转换守卫

一个想法实现装饰器模式[=]的基本状态机中配置默认​​守卫 40=],即它是一个包装器,实现了包装另一个守卫的守卫接口。作为默认的守卫包装,使用了一个简单的守卫实现,它总是 returns true for 评估方法。

代码片段看起来像......首先是守卫:

import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.guard.Guard;
// ... custom States and Events imports

public class GuardDecorator implements Guard<States, Events> {

    private Guard<States, Events> guard;

    public GuardDecorator() {
        this.guard = new DefaultGuard();
    }

    public GuardDecorator(Guard<States, Events> guard) {
        this.guard = guard;
    }

    public void setGuard(Guard<States, Events> guard) {
        this.guard = guard;
    }

    public String wrappedGuardInfo() {
        return this.guard.toString();
    }

    @Override
    public boolean evaluate(StateContext<States, Events> context) {
        return this.guard.evaluate(context);
    }
}

public class DefaultGuard implements Guard<States, Events> {
    @Override
    public boolean evaluate(StateContext<States, Events> context) {
        return true;
    }
}

现在在状态机配置器中使用 GuardDecorator(仅摘录):

// ...
@Bean
public GuardDecorator guard() {
    return new GuardDecorator();
}
// ...
@Override
public void configure(
    StateMachineTransitionConfigurer<States, Events> transitions)
    throws Exception {

    transitions.withExternal()
        .source(States.S1)
        .target(States.S2)
        .event(Events.E1)
        .guard(guard());
    }
// ...

我现在的问题是:

  • 我是否遗漏了文档中的某些内容,是否有内置方法可以做到这一点
  • 任何其他解决方案 以获得基本的实现依赖保护 库中提供的状态机?

没有任何内置功能,但不确定是否必须内置。如果你基于 JavaConfig 做这个配置,你可以在那里创建默认守卫并允许用户自动装配可选的重写实现

Autowired(required=false)
@Qualifier("myGuard")
Guard<States, Events> guard;

或者允许用户覆盖 bean 定义本身。如果在多个配置 类 中创建了相同的 bean,则最后解决的顺序获胜。这个概念在 Spring Umbrella 项目中大量使用,其中默认 bean 存在但允许被用户覆盖。

@Bean(name="myGuard")
public GuardDecorator guard() {
    return new GuardDecorator();
}