使用javaFx进行Spring启动



我正在使用spring boot和javaFx开发java桌面应用程序。这是一个crud应用程序,所以我与mysql数据库工作我希望控制器都是春季启动和javaFx控制器,为此,我使用setControllerFactory() .
这是我的应用程序

应用程序:

package com.gi.quizui;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        javafx.application.Application.launch(QuizApplication.class, args);
    }
}

QuizApplication:

package com.gi.quizui;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.stage.Stage;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ConfigurableApplicationContext;
public class QuizApplication extends Application {
    private ConfigurableApplicationContext applicationContext;
    @Override
    public void init() {
        applicationContext = new SpringApplicationBuilder(com.gi.quizui.Application.class).run();
    }
    @Override
    public void start(Stage stage) {
        applicationContext.publishEvent(new StageReadyEvent(stage));
    }
    @Override
    public void stop() {
        applicationContext.close();
        Platform.exit();
    }
    class StageReadyEvent extends ApplicationEvent {
        public StageReadyEvent(Stage stage) {
            super(stage);
        }
        public ConfigurableApplicationContext getAppContext() {
            return applicationContext;
        }
        public Stage getStage() {
            return ((Stage) getSource());
        }
    }
}

和阶段初始化式:

package com.gi.quizui;
import com.gi.quizui.QuizApplication.StageReadyEvent;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component
public class StageInitializer implements ApplicationListener<StageReadyEvent> {
    @Value("classpath:fxml/quiz.fxml")
    private Resource quizResource;
    public StageInitializer(@Value("${spring.application.ui.title}") String applicationTitle) {
        this.applicationTitle = applicationTitle;
    }
    private String applicationTitle;
    @Override
    public void onApplicationEvent(StageReadyEvent event) {
        Stage stage = event.getStage();
        ConfigurableApplicationContext springContext = event.getAppContext();
        try {
            FXMLLoader fxmlLoader = new FXMLLoader(quizResource.getURL());
            fxmlLoader.setControllerFactory(springContext::getBean);
            Parent parent = fxmlLoader.load();
            stage.setScene(new Scene(parent, 800, 600));
            stage.setTitle(applicationTitle);
            stage.show();
        } catch (IOException e) {
            throw new RuntimeException();
        }
    }
}

我一直得到这个错误:(编辑)

Exception in Application start method
2021-01-16 15:37:15.286  INFO 8652 --- [lication Thread] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2021-01-16 15:37:15.320  INFO 8652 --- [lication Thread] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2021-01-16 15:37:15.343  INFO 8652 --- [lication Thread] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.
Exception in thread "main" java.lang.RuntimeException: Exception in Application start method
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.RuntimeException: javafx.fxml.LoadException: 
/C:/Users/FacilOrdi/IdeaProjects/quizManagement/target/classes/fxml/quiz.fxml:7
    at com.gi.quizui.StageInitializer.onApplicationEvent(StageInitializer.java:40)
    at com.gi.quizui.StageInitializer.onApplicationEvent(StageInitializer.java:16)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:426)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:383)
    at com.gi.quizui.QuizApplication.start(QuizApplication.java:20)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
    ... 1 more
Caused by: javafx.fxml.LoadException: 
/C:/Users/FacilOrdi/IdeaProjects/quizManagement/target/classes/fxml/quiz.fxml:7
    at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2625)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2603)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2466)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2435)
    at com.gi.quizui.StageInitializer.onApplicationEvent(StageInitializer.java:35)
    ... 16 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.gi.controllers.QuizController' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1177)
    at javafx.fxml.FXMLLoader$ValueElement.processAttribute(FXMLLoader.java:938)
    at javafx.fxml.FXMLLoader$InstanceDeclarationElement.processAttribute(FXMLLoader.java:980)
    at javafx.fxml.FXMLLoader$Element.processStartElement(FXMLLoader.java:227)
    at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:752)
    at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2722)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2552)
    ... 19 more

控制器:

package com.gi.controllers;

import org.springframework.stereotype.Component;
@Component
public class QuizController {

}

我不明白为什么它不工作,我发现了相关的问题,但我不明白它是如何工作的。如果有其他方法来做这件事,那就太有帮助了。

为了知道有注释的类,如@Component等,Spring Boot需要在启动时扫描部分类路径。默认情况下,它将扫描包含您传递给SpringApplicationBuilder(在您的情况下是Application)的类的包和所有子包。

根据你设置的方式,它将扫描com.gi.quizui和所有子包。

你的QuizController类不在com.gi.quizui的子包中;它在com.gi.controllers。因此,它不会被找到。

Spring Boot文档中的建议实际上是在包含类或资源的最高级包中使用Application类,在您的情况下可能是com.gi。如果你把那个类移到那个包中,它应该能解决这个问题。

或者,您可以使用@ComponentScan注释覆盖默认行为:

package com.gi.quizui;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan ;
@SpringBootApplication
@ComponentScan(basePackages={"com.gi.quizui","com.gi.controllers"})
public class Application {
    public static void main(String[] args) {
        javafx.application.Application.launch(QuizApplication.class, args);
    }
}

类型安全的替代方法是使用basePackageClasses参数代替basePackages:

package com.gi.quizui;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan ;
import com.gi.controllers.QuizController ;
@SpringBootApplication
@ComponentScan(basePackageClasses={Application.class, QuizController.class})
public class Application {
    public static void main(String[] args) {
        javafx.application.Application.launch(QuizApplication.class, args);
    }
}

最新更新