【问题标题】:How to get ApplicationContext in main function - Spring boot如何在主函数中获取 ApplicationContext - Spring boot
【发布时间】:2017-12-08 14:49:20
【问题描述】:

我想结合两个库 - 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 没有正确注入,但是为什么呢?我做错了什么?

【问题讨论】:

  • 我还可以补充一点,其他网站中有很多以相同方式执行此操作的示例! (例如mkyong.com/spring-boot/…
  • 看看run 方法返回的内容怎么样...另外,您的launch 方法在做什么看起来这是一个JavaFX 应用程序,它实际上并没有使用main在这种情况下。

标签: spring spring-boot javafx


【解决方案1】:

您不能将ApplicationContext(或其他任何东西)注入到调用start()Application 实例中:Application 的实例是由JavaFX 为您创建的,而不是由Spring 创建的。由于它不是 spring 管理的对象,因此 Spring 没有向其中注入任何东西的机制。

将对SpringApplication.run() 的调用移至init() 方法,您可以在其中直接分配上下文。此外,恕我直言,让控制器由 Spring 管理的更好方法是告诉FXMLLoader 通过 Spring 创建控制器,您可以使用控制器工厂来执行此操作。见Dependency Injection and 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();

    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-16
    • 2018-10-12
    • 2020-08-17
    • 2021-10-10
    • 2017-09-23
    • 1970-01-01
    • 2020-01-19
    • 2014-10-03
    相关资源
    最近更新 更多