Spring 状态机 bean 检测不工作
Spring state machine bean detection not working
我目前正在使用 Spring 状态机构建一个小示例项目。
我的配置:
@Configuration
@EnableStateMachine
public class StateMachineConfiguration extends EnumStateMachineConfigurerAdapter<States, Events> {
@Override
public void configure(StateMachineStateConfigurer<States, Events> states)
throws Exception {
states
.withStates()
.initial(States.LOCKED)
.states(EnumSet.allOf(States.class));
}
@Override
public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
throws Exception {
transitions
.withExternal()
.source(States.LOCKED)
.target(States.UNLOCKED)
.event(Events.COIN)
.and()
.withExternal()
.source(States.UNLOCKED)
.target(States.LOCKED)
.event(Events.PUSH);
}
@Bean
public StateMachineListener<States, Events> listener() {
return new StateMachineListenerAdapter<States, Events>() {
@Override
public void stateChanged(State<States, Events> from, State<States, Events> to) {
System.out.println("State change to " + to.getId());
}
};
}
}
当我现在尝试用
注入状态机时
@Autowired
StateMachine<States, Events> stateMachine;
IntelliJ 给了我提示,这不能 autowired 因为那里没有 bean。如果我 运行 应用程序,我也会得到一个例外。
gradle 依赖项:
compile 'org.springframework.statemachine:spring-statemachine-core:2.0.1.
compile group: 'org.springframework.boot', name: 'spring-boot-starter', version: '2.0.1.RELEASE'
compile group: 'org.springframework.shell', name: 'spring-shell-starter', version: '2.0.1.RELEASE'
compile group: 'org.springframework.statemachine', name: 'spring-statemachine-boot', version: '1.2.11.RELEASE'
您可以尝试使用
@EnableStateMachine(name = "myStateMachine")
和
@Autowired
StateMachine<States, Events> myStateMachine;
我不知道问题出在哪里。但以下代码片段对我有用。
@Configuration
@EnableStateMachine
public class StateMachineConfiguration {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Bean
public StateMachine<States, Events> stateMachine(StateMachineListener<States, Events> listener) throws Exception {
StateMachineBuilder.Builder<States, Events> builder = StateMachineBuilder.builder();
builder.configureStates()
.withStates()
.initial(States.LOCKED)
.states(EnumSet.allOf(States.class));
builder.configureTransitions()
.withExternal()
.source(States.LOCKED)
.target(States.UNLOCKED)
.event(Events.COIN)
.and()
.withExternal()
.source(States.UNLOCKED)
.target(States.LOCKED)
.event(Events.PUSH);
StateMachine<States, Events> stateMachine = builder.build();
stateMachine.addStateListener(listener);
return stateMachine;
}
@Bean
public StateMachineListener<States, Events> listener() {
return new StateMachineListenerAdapter<States, Events>() {
@Override
public void stateChanged(State<States, Events> from, State<States, Events> to) {
logger.info("State change to " + to.getId());
}
};
}
}
对我来说,问题是由于不匹配泛型类型参数引起的。因此,我使用 StateMachineStateConfigurer<String, String>
而不是 StateMachineStateConfigurer<States, Events>
,因此未定义 bean 的 <States, Events>
版本。
在你的情况下,检查“States”的导入和“Events”的导入,以确保它们在 bean 定义中以及你使用 @Autowired 的地方相同类。
我也遇到了同样的问题
我做到了。
有效
@SpringBootApplication
@EnableStateMachine
public class StateMachineSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(StateMachineSpringBootApplication.class, args);
}
}
配置
@Configuration
public class MachineConfigurationCustom extends EnumStateMachineConfigurerAdapter<BookStates, BookEvents> {
@Bean
public StateMachine<BookStates, BookEvents> stateMachine(StateMachineListener<BookStates, BookEvents> listener) throws Exception {
StateMachineBuilder.Builder<BookStates, BookEvents> builder =
StateMachineBuilder.builder();
builder.configureStates()
.withStates()
.initial(BookStates.AVAILABLE)
.states(EnumSet.allOf(BookStates.class));
builder.configureTransitions()
.withExternal()
.source(BookStates.AVAILABLE)
.target(BookStates.BORROWED)
.event(BookEvents.BORROW)
.and()
.withExternal()
.source(BookStates.BORROWED)
.target(BookStates.AVAILABLE)
.event(BookEvents.RETURN)
.and()
.withExternal()
.source(BookStates.AVAILABLE)
.target(BookStates.IN_REPAIR)
.event(BookEvents.START_REPAIR)
.and()
.withExternal()
.source(BookStates.IN_REPAIR)
.target(BookStates.AVAILABLE)
.event(BookEvents.END_REPAIR);
StateMachine<BookStates, BookEvents> stateMachine = builder.build();
stateMachine.addStateListener(listener);
return stateMachine;
}
@Override
public void configure(StateMachineConfigurationConfigurer<BookStates, BookEvents> config) throws Exception {
config.withConfiguration()
.autoStartup(true)
.listener(new LoggingMachineListener());
}
}
监听器
@Component
public class LoggingMachineListener implements StateMachineListener<BookStates, BookEvents> {
private static final Logger LOGGER = LoggingUtils.LOGGER;
@Override
public void stateChanged(State<BookStates, BookEvents> from, State<BookStates, BookEvents> to) {
LOGGER.info("State changed from {} to {}", getStateInfo(from), getStateInfo(to));
}
@Override
public void stateEntered(State<BookStates, BookEvents> state) {
LOGGER.info("Entered state {}", getStateInfo(state));
}
@Override
public void stateExited(State<BookStates, BookEvents> state) {
LOGGER.info("Exited state {}", getStateInfo(state));
}
@Override
public void stateMachineStarted(StateMachine<BookStates, BookEvents> stateMachine) {
LOGGER.info("Machine started: {}", stateMachine);
}
@Override
public void stateMachineStopped(StateMachine<BookStates, BookEvents> stateMachine) {
LOGGER.info("Machine stopped: {}", stateMachine);
}
@Override
public void stateMachineError(StateMachine<BookStates, BookEvents> stateMachine, Exception exception) {
LOGGER.error("Machine error: {}", stateMachine);
}
@Override
public void extendedStateChanged(Object key, Object value) {
LOGGER.info("Extended state changed: [{}: {}]", key, value);
}
......
}
亚军
@Component
public class RunnerStateMachineWithCommandLine implements CommandLineRunner {
private final StateMachine<BookStates, BookEvents> stateMachine;
@Autowired
public RunnerStateMachineWithCommandLine(StateMachine<BookStates, BookEvents> stateMachine) {
this.stateMachine = stateMachine;
}
@Override
public void run(String... args){
stateMachine.start();
stateMachine.sendEvent(BookEvents.RETURN);
stateMachine.sendEvent(BookEvents.BORROW);
stateMachine.stop();
}
}
在配置class中,可以添加注解@EnableStateMachineFactory
就可以了,
@EnableStateMachineFactory
@Configuration
@Log
public class EmployeeStateMachineConfig extends StateMachineConfigurerAdapter<EmployeeStates, EmployeeEvents> {
}
我目前正在使用 Spring 状态机构建一个小示例项目。
我的配置:
@Configuration
@EnableStateMachine
public class StateMachineConfiguration extends EnumStateMachineConfigurerAdapter<States, Events> {
@Override
public void configure(StateMachineStateConfigurer<States, Events> states)
throws Exception {
states
.withStates()
.initial(States.LOCKED)
.states(EnumSet.allOf(States.class));
}
@Override
public void configure(StateMachineTransitionConfigurer<States, Events> transitions)
throws Exception {
transitions
.withExternal()
.source(States.LOCKED)
.target(States.UNLOCKED)
.event(Events.COIN)
.and()
.withExternal()
.source(States.UNLOCKED)
.target(States.LOCKED)
.event(Events.PUSH);
}
@Bean
public StateMachineListener<States, Events> listener() {
return new StateMachineListenerAdapter<States, Events>() {
@Override
public void stateChanged(State<States, Events> from, State<States, Events> to) {
System.out.println("State change to " + to.getId());
}
};
}
}
当我现在尝试用
注入状态机时@Autowired
StateMachine<States, Events> stateMachine;
IntelliJ 给了我提示,这不能 autowired 因为那里没有 bean。如果我 运行 应用程序,我也会得到一个例外。
gradle 依赖项:
compile 'org.springframework.statemachine:spring-statemachine-core:2.0.1.
compile group: 'org.springframework.boot', name: 'spring-boot-starter', version: '2.0.1.RELEASE'
compile group: 'org.springframework.shell', name: 'spring-shell-starter', version: '2.0.1.RELEASE'
compile group: 'org.springframework.statemachine', name: 'spring-statemachine-boot', version: '1.2.11.RELEASE'
您可以尝试使用
@EnableStateMachine(name = "myStateMachine")
和
@Autowired
StateMachine<States, Events> myStateMachine;
我不知道问题出在哪里。但以下代码片段对我有用。
@Configuration
@EnableStateMachine
public class StateMachineConfiguration {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Bean
public StateMachine<States, Events> stateMachine(StateMachineListener<States, Events> listener) throws Exception {
StateMachineBuilder.Builder<States, Events> builder = StateMachineBuilder.builder();
builder.configureStates()
.withStates()
.initial(States.LOCKED)
.states(EnumSet.allOf(States.class));
builder.configureTransitions()
.withExternal()
.source(States.LOCKED)
.target(States.UNLOCKED)
.event(Events.COIN)
.and()
.withExternal()
.source(States.UNLOCKED)
.target(States.LOCKED)
.event(Events.PUSH);
StateMachine<States, Events> stateMachine = builder.build();
stateMachine.addStateListener(listener);
return stateMachine;
}
@Bean
public StateMachineListener<States, Events> listener() {
return new StateMachineListenerAdapter<States, Events>() {
@Override
public void stateChanged(State<States, Events> from, State<States, Events> to) {
logger.info("State change to " + to.getId());
}
};
}
}
对我来说,问题是由于不匹配泛型类型参数引起的。因此,我使用 StateMachineStateConfigurer<String, String>
而不是 StateMachineStateConfigurer<States, Events>
,因此未定义 bean 的 <States, Events>
版本。
在你的情况下,检查“States”的导入和“Events”的导入,以确保它们在 bean 定义中以及你使用 @Autowired 的地方相同类。
我也遇到了同样的问题
我做到了。
有效
@SpringBootApplication
@EnableStateMachine
public class StateMachineSpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(StateMachineSpringBootApplication.class, args);
}
}
配置
@Configuration
public class MachineConfigurationCustom extends EnumStateMachineConfigurerAdapter<BookStates, BookEvents> {
@Bean
public StateMachine<BookStates, BookEvents> stateMachine(StateMachineListener<BookStates, BookEvents> listener) throws Exception {
StateMachineBuilder.Builder<BookStates, BookEvents> builder =
StateMachineBuilder.builder();
builder.configureStates()
.withStates()
.initial(BookStates.AVAILABLE)
.states(EnumSet.allOf(BookStates.class));
builder.configureTransitions()
.withExternal()
.source(BookStates.AVAILABLE)
.target(BookStates.BORROWED)
.event(BookEvents.BORROW)
.and()
.withExternal()
.source(BookStates.BORROWED)
.target(BookStates.AVAILABLE)
.event(BookEvents.RETURN)
.and()
.withExternal()
.source(BookStates.AVAILABLE)
.target(BookStates.IN_REPAIR)
.event(BookEvents.START_REPAIR)
.and()
.withExternal()
.source(BookStates.IN_REPAIR)
.target(BookStates.AVAILABLE)
.event(BookEvents.END_REPAIR);
StateMachine<BookStates, BookEvents> stateMachine = builder.build();
stateMachine.addStateListener(listener);
return stateMachine;
}
@Override
public void configure(StateMachineConfigurationConfigurer<BookStates, BookEvents> config) throws Exception {
config.withConfiguration()
.autoStartup(true)
.listener(new LoggingMachineListener());
}
}
监听器
@Component
public class LoggingMachineListener implements StateMachineListener<BookStates, BookEvents> {
private static final Logger LOGGER = LoggingUtils.LOGGER;
@Override
public void stateChanged(State<BookStates, BookEvents> from, State<BookStates, BookEvents> to) {
LOGGER.info("State changed from {} to {}", getStateInfo(from), getStateInfo(to));
}
@Override
public void stateEntered(State<BookStates, BookEvents> state) {
LOGGER.info("Entered state {}", getStateInfo(state));
}
@Override
public void stateExited(State<BookStates, BookEvents> state) {
LOGGER.info("Exited state {}", getStateInfo(state));
}
@Override
public void stateMachineStarted(StateMachine<BookStates, BookEvents> stateMachine) {
LOGGER.info("Machine started: {}", stateMachine);
}
@Override
public void stateMachineStopped(StateMachine<BookStates, BookEvents> stateMachine) {
LOGGER.info("Machine stopped: {}", stateMachine);
}
@Override
public void stateMachineError(StateMachine<BookStates, BookEvents> stateMachine, Exception exception) {
LOGGER.error("Machine error: {}", stateMachine);
}
@Override
public void extendedStateChanged(Object key, Object value) {
LOGGER.info("Extended state changed: [{}: {}]", key, value);
}
......
}
亚军
@Component
public class RunnerStateMachineWithCommandLine implements CommandLineRunner {
private final StateMachine<BookStates, BookEvents> stateMachine;
@Autowired
public RunnerStateMachineWithCommandLine(StateMachine<BookStates, BookEvents> stateMachine) {
this.stateMachine = stateMachine;
}
@Override
public void run(String... args){
stateMachine.start();
stateMachine.sendEvent(BookEvents.RETURN);
stateMachine.sendEvent(BookEvents.BORROW);
stateMachine.stop();
}
}
在配置class中,可以添加注解@EnableStateMachineFactory
就可以了,
@EnableStateMachineFactory
@Configuration
@Log
public class EmployeeStateMachineConfig extends StateMachineConfigurerAdapter<EmployeeStates, EmployeeEvents> {
}