import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.StateContext;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineModelConfigurer;
import org.springframework.statemachine.config.model.DefaultStateMachineComponentResolver;
import org.springframework.statemachine.config.model.StateMachineComponentResolver;
import org.springframework.statemachine.config.model.StateMachineModelFactory;
import org.springframework.statemachine.guard.Guard;
import org.springframework.statemachine.uml.UmlStateMachineModelFactory;
@Configuration
@EnableStateMachine
public class StateMachineConfiguration extends StateMachineConfigurerAdapter<String, String> {
@Override
public void configure(StateMachineModelConfigurer<String, String> model) throws Exception {
model.withModel().factory(modelFactory());
}
@Bean
public StateMachineModelFactory<String, String> modelFactory() {
UmlStateMachineModelFactory factory =
new UmlStateMachineModelFactory("classpath:state-machine.uml");
// actions and guards registered by DefaultStateMachineComponentResolver isn't resolved
factory.setStateMachineComponentResolver(stateMachineComponentResolver());
// if uncomment, it works
// factory.registerGuard("myGuard", myGuard());
return factory;
}
@Bean
public StateMachineComponentResolver<String, String> stateMachineComponentResolver() {
DefaultStateMachineComponentResolver<String, String> resolver =
new DefaultStateMachineComponentResolver<>();
resolver.registerGuard("myGuard", myGuard());
return resolver;
}
public Guard<String, String> myGuard() {
return context -> false;
}
}
Running the application configured like I did before, I'm getting this error.
***************************
APPLICATION FAILED TO START
***************************
Description:
A component required a bean named 'myGuard' that could not be found.
Action:
Consider defining a bean named 'myGuard' in your configuration.
But, if you register the guard direct by UmlStateMachineModelFactory factory, it works well.
I think the problem is here AbstractStateMachineModelFactory#resolveAction(id).
public Action<S, E> resolveAction(String id) {
// throw the exception. So this.stateMachineComponentResolver.resolveAction(id) isn't called.
Action<S, E> a = this.internalResolver.resolveAction(id);
if (a == null && this.stateMachineComponentResolver != null) {
a = this.stateMachineComponentResolver.resolveAction(id);
}
if (a == null) {
throw new RuntimeException("Can't resolve action with id " + id + " either from registered actions nor beanfactory");
} else {
return a;
}
}
Running the application configured like I did before, I'm getting this error.
But, if you register the guard direct by UmlStateMachineModelFactory factory, it works well.
I think the problem is here AbstractStateMachineModelFactory#resolveAction(id).