I have a JavaFX application with Spring. I have a bean in a Configuration class which is being correctly added to the SpringContext, and can be retrieved manually, but it is not getting autowired into a class annotated @Component. I have summarised the code below.
@SpringBootApplicationpublic class BoothApplication extends javafx.application.Application { // this is temporarily static for debug purposes public static ConfigurableApplicationContext springContext; private Parent rootNode; private Scene threeCardScene, debugScene, ezzieScene; @Autowired private StateMachineConfiguration stateMachineSupplier; @Autowired private GameModel gameModel; @Override public void start(Stage prinaryStage) throws IOException {<snip> mainStage.show(); } public static void main(String[] args) { launch(); } @Override public void init() throws Exception { springContext = SpringApplication.run(BoothApplication.class); FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("/org/overworld/tarotbooth/ezzie.fxml")); fxmlLoader.setControllerFactory(springContext::getBean); rootNode = fxmlLoader.load(); } @Override public void stop() throws Exception { springContext.close(); }}
I have a bean that is correctly initialised:
@Configurationpublic class StateMachineConfiguration { @Bean public StateMachine<State, Trigger> stateMachine() { StateMachineConfig<State, Trigger> config = new StateMachineConfig<State, Trigger>(); /* @formatter:off */ config.configure(State.IDLE) .permit(Trigger.APPROACH_SENSOR, State.CURIOUS) .permit(Trigger.PRESENCE_SENSOR, State.ENGAGED) .onEntry(StateMachineConfiguration::idle) .ignore(Trigger.PAST_READ) .ignore(Trigger.PRESENT_READ) .ignore(Trigger.FUTURE_READ) .ignore(Trigger.PRINTER_ERROR) .ignore(Trigger.TIMEOUT) .ignore(Trigger.ADVANCE) .ignore(Trigger.BAD_PLACEMENT);<snip> /* @formatter:on */ // config.generateDotFileInto(System.out, true); StateMachine<State, Trigger> stateMachine = new StateMachine<State, Trigger>(State.IDLE, config); stateMachine.fireInitialTransition(); return stateMachine; } private static void idle() { System.out.println("idle"); }}
I can access the bean directly via springContext.getBean, but it is not getting autowired:
@Componentpublic class DebugController implements javafx.fxml.Initializable { @Autowired private StateMachine<State, Trigger> stateMachine; @Autowired private GameModel gameModel; // this is also null @Autowired private Deck deck; // this is also null @FXML private ToggleButton approachToggle; @Override public void initialize(URL url, ResourceBundle rb) { // this way works stateMachine = BoothApplication.springContext.getBean(StateMachine.class); //this way doesn't, statemachine is null approachToggle.setOnAction(e -> stateMachine.fire(Trigger.APPROACH_SENSOR)); }}
All the package hierarchy is under the package where the @SpringBootApplication is located, it's not being missed in the componentscan. It's like the DebugController is not getting injected. I've checked all the imports for imposters of the same name. I doubt it's anything with the generics as the other autowired fields are null too.