弹簧状态机动态配置

时间:2018-12-04 23:00:15

标签: java spring state-machine spring-statemachine

我正在使用弹簧状态机版本2.0.3,并且试图动态更新状态机的配置。我有一个用@EnableStateMachineFactory注释的类,它为StateMachineService提供了配置,我想在该类中更新配置。

我将接受一个包含状态和转换信息的JSON有效负载,并根据其构建状态机。问题是,尽管我可以更新配置,但是没有任何要求该Bean获取更新的StateMachineFactory的问题。我怀疑Spring IoC容器是否保留了基础StateMachineModel的引用,这就是为什么StateMachineFactory没有用新配置构建的原因(因为它认为已经有了)。

我的配置类代码在这里:

@Configuration
@EnableStateMachineFactory(name = "default_factory")
@Service(value = "default_config")
public class StateMachineConfig extends StateMachineConfigurerAdapter<States, String> {

    private boolean update = false;

    @Override
    public void configure(StateMachineTransitionConfigurer<States, String> transitions) throws Exception {

        transitions
                .withExternal()
                .source(INITIAL).target(NEXT).event("INITIAL_NEXT");

        if (update) {
            // add some new transition
            transitions
                    .withExternal()
                    .source(HOSPITAL).target(FINAL).event("HOSPITAL_FINAL").action(specialAction());
        }

    }

    public void updateTransition() {
        update = !update;
    }

...

}

我为调用配置并尝试重新加载工厂的类的代码如下:

@Service
public class MachineHandler {

    private ApplicationContext context;
    private DefaultListableBeanFactory beanFactory;

    private Map<String, StateMachineService> machineServices = new HashMap<>();

    public MachineHandler(ApplicationContext context, DefaultListableBeanFactory beanFactory) {
        this.context = context;
        this.beanFactory = beanFactory;
    }

    public void updateMachine() {
        StateMachineConfig config = context.getBean("default_config", StateMachineConfig.class);

        config.updateTransition();

        beanFactory.destroySingleton("default_factory");

        StateMachineFactory<States, String> factory = context.getBean("default_factory", StateMachineFactory.class);\
        machineServices.put(id, new DefaultStateMachineService<>(factory, persister));
    }

    public StateMachineService<States, String> getMachine(String id) {

        StateMachineService service = machineServices.get(id);

        if (service == null) {
            String factoryId = id + "_factory";
            StateMachineFactory<States, String> factory = context.getBean(factoryId, StateMachineFactory.class);
            service = new DefaultStateMachineService<>(factory);
            machineServices.put(id, service);
        }

        return service;
    }

}

有人知道如何重新加载工厂,以便它再次调用configure方法,并且只要有工厂bean就会得到更新的工厂?还是有另一种方法可以实现我想要做的事情?

0 个答案:

没有答案