SpringBoot整合JavaFX多窗口时新窗口服务注入为空问题求解
问题原因
新窗口依赖注入为null的核心原因是:你在SampleController中新建FXMLLoader加载dish-builder.fxml时,没有为该加载器配置Spring上下文的控制器工厂。默认FXMLLoader会通过反射无参构造自行创建Controller实例,这个实例不归Spring容器管理,所有@Autowired标记的依赖都不会被注入,自然全是null。
你主类中初始化首个窗口的FXMLLoader时,已经配置了fxmlLoader.setControllerFactory(springContext::getBean),这就是第一个窗口的Controller、Service能正常运行的原因。
修复方法
直接调用主类中定义的静态springContext属性,给新创建的FXMLLoader设置相同的控制器工厂即可,修改addNoweOknoClicked方法代码如下:
@FXML void addNoweOknoClicked(ActionEvent event) { try { Stage stage = (Stage)anchorPane.getScene().getWindow(); FXMLLoader fxmlLoader = new FXMLLoader(); fxmlLoader.setLocation(getClass().getResource("/dish-builder.fxml")); // 新增该行:指定Controller从Spring容器获取,触发依赖注入逻辑 fxmlLoader.setControllerFactory(MyAppSpringApplication.springContext::getBean); AnchorPane root = fxmlLoader.load(); stage.setTitle("Sample app"); Scene scene = new Scene(root); stage.setScene(scene); stage.show(); }catch (IOException e){ e.printStackTrace(); } }
优化建议
为了避免后续每次新建FXMLLoader都重复配置控制器工厂,可以在主类中抽一个公共静态工具方法,统一生成绑定Spring上下文的FXMLLoader:
public static FXMLLoader loadFxml(String fxmlPath) { FXMLLoader loader = new FXMLLoader(); loader.setLocation(MyAppSpringApplication.class.getResource(fxmlPath)); loader.setControllerFactory(springContext::getBean); return loader; }
后续加载任意FXML文件时,直接调用该方法传入FXML路径即可,不会再出现漏配导致的注入null问题。
另外需要确认DishBuilderService已经添加了@Service等Spring组件注解,且所在包在SpringBoot的默认扫描范围内,否则Spring容器不会管理该Bean,同样会出现注入失败。
内容的提问来源于stack exchange,提问作者Marcin Knapik
相关产品推荐
相关产品推荐

