Spring

javaFx로 Spring 부팅

기록만이살길 2021. 3. 4. 07:06
반응형

javaFx로 Spring 부팅

1. 질문(문제점):

저는 스프링 부트와 javaFx를 사용하는 자바 데스크톱 앱을 개발 중입니다. 그것은 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 {


}

작동하지 않는 이유를 이해하지 못하고 관련 질문을 찾았지만 작동 방식을 알 수 없습니다. 다른 대안이 있다면 매우 도움이 될 것입니다.

2. 해결방안:

@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);
    }
}
65750639
반응형