我想结合两个库 - JavaFx 和 Spring Boot,因此我需要在主类的 start() 方法中有一个ApplicationContext
的实例:
主类:
@SpringBootApplication
public class JavaFXandSpringBootTestApplication extends Application{
@Autowired
ApplicationContext ctx;
public static void main(String[] args) {
SpringApplication.run(JavaFXandSpringBootTestApplication.class, args);
launch();
}
@Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/LogIn.fxml"));
loader.setController(ctx.getBean(LogInController.class)); // HERE OCCURES ERROR
Scene scene = new Scene((Parent)loader.load());
stage.setScene(scene);
stage.show();
}
}
控制器类:
@Component
public class LogInController {
}
正如我所阅读的纪录片@SpringBootApplication
可以自动检测组件,并且在引擎盖下还用@Configuration
注释类。 那么现在,为什么我在推荐行中收到一个 NullPointerException?这是因为ctx没有正确注射,但为什么呢?我做错了什么?
您不能将ApplicationContext
(或其他任何内容)注入到调用start()
的Application
实例中:该Application
实例是由JavaFX创建的,而不是由Spring创建的。由于它不是 Spring 管理的对象,因此 Spring 没有向其中注入任何内容的机制。
将调用移动到SpringApplication.run()
init()
方法,您可以在其中直接分配上下文。此外,恕我直言,让控制器由 Spring 管理的更好方法是告诉FXMLLoader
通过 Spring 创建控制器,您可以使用控制器工厂执行此操作。请参阅依赖注入和 JavaFX。
@SpringBootApplication
public class JavaFXandSpringBootTestApplication extends Application{
private ApplicationContext ctx;
public static void main(String[] args) {
launch(args);
}
@Override
public void init() {
String[] args = getParameters().getRaw().toArray(new String[0]);
ctx = SpringApplication.run(JavaFXandSpringBootTestApplication.class, args);
}
@Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/LogIn.fxml"));
loader.setControllerFactory(ctx::getBean);
// or, if you prefer,
// loader.setController(ctx.getBean(LoginController.class));
// though the controller factory approach lets you use `fx:controller` as usual.
Scene scene = new Scene((Parent)loader.load());
stage.setScene(scene);
stage.show();
}
}