如何在主函数中获取应用程序上下文 - Spring boot



我想结合两个库 - 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();
}
}

相关内容

最新更新