Как внедрить бины в основной класс приложения SpringBoot & JavaFx - PullRequest
0 голосов
/ 06 октября 2019

Я начинаю с JavaFX и хотел бы интегрировать его с Spring Boot.

Я проследил за этим блогом, в котором описывается, как это делается: https://better -coding.com /javafx-spring-boot-gradle-project-setup-guide-and-test /

Он имеет следующие методы, среди прочего:

public static void main(String[] args) {
    launch(args);
}
@Override
public void init() throws Exception {
    springContext = SpringApplication.run(MyApp.class);
    fxmlLoader = new FXMLLoader();
    fxmlLoader.setControllerFactory(springContext::getBean);
}
@Override
public void start(Stage primaryStage) throws Exception{
    fxmlLoader.setLocation(getClass().getResource("/fxml/sample.fxml"));
    rootNode = fxmlLoader.load();

    primaryStage.setTitle("Hello World");
    Scene scene = new Scene(rootNode, 800, 600);
    primaryStage.setScene(scene);
    primaryStage.show();
}

Как видите,методы init() и start() вводят жесткую зависимость между моим основным классом и классами FXMLLoader и Scene. Поэтому я хотел бы удалить эти зависимости, и поэтому я создал bean-компонент для FXMLLoader (для начала) в своем классе AppConfig:

@Bean
public FXMLLoader fxmlLoader() {
    return new FXMLLoader();
}

И затем я автоматически связал его в своем основном классе(autowire для свойства) и удалил создание экземпляра FXMLLoader из метода init():

@Autowired
private FXMLLoader fxmlLoader;

Когда я запускаю приложение, оно завершается с ошибкой NullPointerException, поскольку fxmlLoader равно нулю. В качестве альтернативы я получаю компонент напрямую из контекста с помощью метода getBean():

@Override
public void init() throws Exception {
    springContext = SpringApplication.run(SpringFxApplication.class);
    fxmlLoader = springContext.getBean(FXMLLoader.class);
    fxmlLoader.setControllerFactory(springContext::getBean);
}

Поскольку это считается плохой практикой, как я могу внедрить компонент в мой основной класс? ?

ПОЛНЫЙ КОД:

@SpringBootApplication
@ComponentScan(basePackages = "com.testpackage")
public class SpringFxApplication extends Application {

    @Autowired
    private FXMLLoader fxmlLoader;
    private ConfigurableApplicationContext springContext;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void init() throws Exception {
        springContext = SpringApplication.run(SpringFxApplication.class);
        //fxmlLoader = springContext.getBean(FXMLLoader.class);
        fxmlLoader.setControllerFactory(springContext::getBean);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        fxmlLoader.setLocation(getClass().getResource("/fxml/sample.fxml"));
        Parent rootNode = fxmlLoader.load();

        primaryStage.setTitle("Hello World");
        Scene scene = new Scene(rootNode, 800, 600);
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    @Override
    public void stop() {
        springContext.stop();
    }
}

@Configuration
public class AppConfig {

    @Bean
    public FXMLLoader fxmlLoader() {
        return new FXMLLoader();
    }
}
...