Spring State Machine динамическая конфигурация - PullRequest
0 голосов
/ 05 декабря 2018

Я использую Spring State Machine версии 2.0.3 и пытаюсь динамически обновить конфигурацию конечного автомата.У меня есть класс, помеченный @EnableStateMachineFactory, который предоставляет конфигурацию для StateMachineService, именно в этом классе я хочу обновить конфигурацию.

Я буду принимать полезную нагрузку JSON, которая содержит состояние ипередача информации и построение конечного автомата из нее.Проблема заключается в том, что, хотя я могу обновить конфигурацию, ничего, требующего, чтобы компонент получил обновленное 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;
    }

}

У кого-нибудь есть идеи?Как перезагрузить фабрику, чтобы она снова вызывала методы конфигурации, и я получал обновленную фабрику всякий раз, когда получал фабричный бин?Или есть другой способ добиться того, что я пытаюсь сделать?

...