Saya menggunakan Spring JPA dengan OpenJFX. Ini adalah proyek JavaFX-weaver, cukup tambahkan pegas -boot-start-data-jpa di dalam pom.

Namun waktu mulai Spring JPA saya adalah 15-20 detik dan UI tidak akan ditampilkan sampai pegas diinisialisasi. Ketika pengguna akan memulai aplikasi, dibutuhkan banyak waktu, setiap saat!

Sebagai solusinya saya mencoba membuat aplikasi java fx sederhana tanpa Spring (menggunakan demo ini di sini) dan kemudian mulai dari sana dalam metode utama metode utama dari pegas di atas tombol (lihat contoh di bawah). Itu akan mulai musim semi, tetapi dependensi dan properti tidak dimuat.

Apakah Anda tahu cara yang baik untuk mempraktekkan kasus itu? Setiap bantuan diterima.

Terima kasih

AppBootstrap (Java + OpenJFX)

public class AppBootstrap extends Application {

    @Override
    public void start(Stage primaryStage) {

        Button btn = new Button();

        // start spring jpa main method
        btn.setOnAction(event -> App.main(new String[]{""})); 

        StackPane root = new StackPane();
        root.getChildren().add(btn);

        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }

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

Aplikasi (Spring JPA + javafx-weaver)

@SpringBootApplication
public class App {
    public static void main(String[] args) {
        Application.launch(SpringbootJavaFxApplication.class, args);
    }
}
3
user182410 17 April 2020, 17:47

1 menjawab

Jawaban Terbaik

Startup Aplikasi bertenaga JPA meningkatkan waktu buka untuk ApplicationContext. Meskipun Anda dapat membuat segalanya lebih cepat dengan tidak memeriksa atau membuat skema basis data, mis. dengan menyetel hibernate.hbm2ddl.auto=none, ini bukan opsi terbaik.

Secara desain, tahap utama ditampilkan setelah ApplicationContext dimuat, karena harus dapat disuntikkan ketergantungan.

Praktik terbaik yang saya sarankan adalah menggunakan layar splash saat memuat ApplicationContext. Agak rumit, karena Anda memiliki Utas terpisah, tetapi kira-kira terlihat seperti ini:

Buat jendela pembuka

public class Splash {

    private static final int SPLASH_WIDTH = 200;
    private static final int SPLASH_HEIGHT = 200;

    private final Parent parent;
    private final Stage stage; 

    public Splash() {
        this.stage = new Stage();
        stage.setWidth(SPLASH_WIDTH);
        stage.setHeight(SPLASH_HEIGHT);
        Label progressText = new Label("Application loading ...");
        VBox splashLayout = new VBox();
        splashLayout.setAlignment(Pos.CENTER);
        splashLayout.getChildren().addAll(progressText);
        progressText.setAlignment(Pos.CENTER);
        splashLayout.setStyle(
                "-fx-padding: 5; " +
                        "-fx-background-color: white; " +
                        "-fx-border-width:5; " +
                        "-fx-border-color: white;"
        );
        splashLayout.setEffect(new DropShadow());
        this.parent = splashLayout;
    }

    public void show() {
        Scene splashScene = new Scene(parent);
        stage.initStyle(StageStyle.UNDECORATED);
        final Rectangle2D bounds = Screen.getPrimary().getBounds();
        stage.setScene(splashScene);
        stage.setX(bounds.getMinX() + bounds.getWidth() / 2 - SPLASH_WIDTH / 2.0);
        stage.setY(bounds.getMinY() + bounds.getHeight() / 2 - SPLASH_HEIGHT / 2.0);
        stage.show();
    }

    public void hide() {
        stage.toFront();
        FadeTransition fadeSplash = new FadeTransition(Duration.seconds(0.3), parent);
        fadeSplash.setFromValue(1.0);
        fadeSplash.setToValue(0.0);
        fadeSplash.setOnFinished(actionEvent -> stage.hide());
        fadeSplash.play();
    }
}

Inisialisasi Aplikasi

public class SpringbootJavaFxApplication extends Application {

    private ConfigurableApplicationContext context;

    class ApplicationContextLoader extends Task<Void> {

        private final Stage primaryStage;

        ApplicationContextLoader(Stage primaryStage) {
            this.primaryStage = primaryStage;
        }

        @Override
        protected Void call() {
            ApplicationContextInitializer<GenericApplicationContext> initializer =
                    context -> {
                        context.registerBean(Application.class, () -> SpringbootJavaFxApplication.this);
                        context.registerBean(Stage.class, () -> primaryStage);
                        context.registerBean(Parameters.class,
                                SpringbootJavaFxApplication.this::getParameters); // for demonstration, not really needed
                    };
            SpringbootJavaFxApplication.this.context = new SpringApplicationBuilder()
                    .sources(JavaFxSpringbootDemo.class)
                    .initializers(initializer)
                    .run(getParameters().getRaw().toArray(new String[0]));

            return null;
        }
    }

    @Override
    public void start(Stage primaryStage) {
        var splash = new Splash();
        splash.show();
        final ApplicationContextLoader applicationContextLoader = new ApplicationContextLoader(primaryStage);
        applicationContextLoader.stateProperty().addListener((observableValue, oldState, newState) -> {
            if (newState == Worker.State.SUCCEEDED) {
                context.publishEvent(new StageReadyEvent(primaryStage));
                splash.hide();
            }
        });
        new Thread(applicationContextLoader).start();
    }

    @Override
    public void stop() {
        this.context.close();
        Platform.exit();
    }
}
1
rgielen 24 April 2020, 06:57