You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring State Machine中从Java代码动态设置UML时间事件的周期值

动态设置Spring State Machine时间事件的周期值

要解决在Spring UML状态机中动态修改时间事件周期的问题,核心是利用Opaque Expression + Spring Bean的组合,让时间事件的周期值可以从Java代码中动态更新。以下是具体步骤和代码示例:

1. 调整UML模型中的Opaque Expression

你已经在TimeEvent2的when部分使用了Opaque Expression并设置了language="bean",只需要微调body内容,使其指向Java Bean的方法(确保能动态获取最新值):

原UML中TimeEvent2的OpaqueExpression body是mT,建议修改为mT.getDelay(),这样Spring会主动调用Bean的方法获取最新时间值。

对应的UML关键片段:

<packagedElement xmi:type="uml:TimeEvent" xmi:id="_YXALUCE8EeyjDr-lLLuZXg" name="TimeEvent2" visibility="protected" isRelative="true">
 <when xmi:type="uml:TimeExpression" xmi:id="_ZjjN0CHHEeyjDr-lLLuZXg">
 <expr xmi:type="uml:OpaqueExpression" xmi:id="_ZjjN0SHHEeyjDr-lLLuZXg" name="mT">
 <language>bean</language>
 <body>mT.getDelay()</body>
 </expr>
 </when>
</packagedElement>

2. 定义Java侧的动态时间提供者Bean

创建一个可动态修改的Bean,用来存储和返回时间事件的周期值,需要提供获取和设置时间值的方法:

import org.springframework.stereotype.Component;

@Component("mT")
public class DynamicTimeProvider {
    // 初始周期值(单位:毫秒)
    private long delay = 2000;

    // 获取当前周期值
    public long getDelay() {
        return delay;
    }

    // 动态更新周期值
    public void setDelay(long delay) {
        this.delay = delay;
    }
}

这里用@Component("mT")指定Bean名称为mT,和UML中OpaqueExpression的body内容完全对应。

3. 在业务代码中动态修改时间值

通过注入DynamicTimeProvider Bean,你可以在任意业务逻辑中修改时间事件的周期值:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class StateMachineService {

    @Autowired
    private DynamicTimeProvider mT;

    // 示例方法:将TimeEvent2的周期更新为3000毫秒
    public void updateTimeEventDelay(long newDelay) {
        mT.setDelay(newDelay);
        // 后续TimeEvent2触发时会自动使用新的周期值
    }
}

原理说明

Spring State Machine在解析language="bean"的Opaque Expression时,会使用Spring表达式语言(SpEL)解析body内容:

  • 它会查找名称为mT的Bean,然后调用getDelay()方法获取最新的时间值
  • 每次触发时间事件前,都会重新解析这个表达式,所以修改DynamicTimeProvider中的值后,下一次时间事件会自动应用新周期

替代方案:用原子类简化实现

如果你不想自定义类,也可以用AtomicLong结合Supplier来实现:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.Supplier;

@Configuration
public class TimeConfig {

    @Bean("mT")
    public Supplier<Long> timeSupplier() {
        AtomicLong dynamicDelay = new AtomicLong(2000);
        return dynamicDelay::get;
    }

    // 提供修改时间的方法
    public void updateTimeDelay(long newDelay) {
        ((AtomicLong)((SuppliedSupplier) timeSupplier()).getSupplier()).set(newDelay);
    }
}

此时UML中的OpaqueExpression body可以直接写mT,因为Spring会自动调用Supplier的get()方法获取值。

内容的提问来源于stack exchange,提问作者Dev1819

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:27:46