2

JavaFXアプリケーションでApplicationContextを使用することに興味がありました。サブクラス自体Applicationの属性としてApplicationContextを処理するよりスマートな方法があるかどうか自問します。 Gui.classからApplicationContextを分離するために、さらにGui.classのバネ成分を注入するため@Autowiredアノテーションを使用するJavaFXアプリケーションのSpringアプリケーションコンテキスト

@Configuration 
@ComponentScan("...") 
public class Gui extends Application { 

    private AnnotationConfigApplicationContext context; 

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

    /* (non-Javadoc) 
    * @see javafx.application.Application#start(javafx.stage.Stage) 
    */ 

    @Override 
    public void start(Stage stage) throws Exception {  
     context = new AnnotationConfigApplicationContext(Gui.class); 
     //...   
    }  
} 

I目的。

答えて

2

最初に、アプリケーション構成をApplicationサブクラスから分離します。 JavaFXはアプリケーションサブクラスのインスタンスを作成します。そのクラスのインスタンスは1つだけです。 Springはすべての設定クラスのインスタンスを作成します。したがって、アクセス権がなくても、意図した用途ではないApplicationクラスの複数のインスタンスになります。

あなたが探している分離については、ApplicationContextとの作成と対話をUIの構築と構成から分離して、アプリケーションのビジネス層と対話させることですしかし、私はあなたがそうするべきである方法からこれを後ろ向きに見ていると思います。 Applicationクラス、特にstart()メソッドは、JavaFXアプリケーションのエントリポイントです。 FXフレームワークは起動時にいくつかのハウスキーピング(FXツールキットの起動など)を行い、そのクラスのインスタンスを作成し、startメソッドを呼び出します。これがアプリケーションの基本アセンブリを行う場所なので、ApplicationContextを作成し、そこから1つまたは2つのBeanを取得するのは自然で正確な場所です。これをUIの作成とコンフィグレーションと区別したい場合は、別の場所に移動する必要があるUIの作成とコンフィグレーションです。 Applicationクラスの唯一の責任は、アプリケーションを起動することです。この方法では、そのクラスに注入する状態はまったくありません。このアプローチを使用

は、最小限の春パワードFXアプリケーションは、次のようになります。

をAppConfig.java:

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.Scope; 

@Configuration 
public class AppConfig { 

    @Bean 
    public Service service() { 
     return new Service(); 
    } 

    @Bean 
    @Scope("prototype") 
    public Gui gui() { 
     return new Gui(); 
    } 
} 

Service.java:

public class Service { 

    public String confirmationMessage() { 
     return "You have been confirmed"; 
    } 
} 

Gui.java(ノートこれは現在サブクラスApplicationではありませんが、ほぼすべてのGUI作業を行います)。

import javax.annotation.PostConstruct; 
import javax.inject.Inject; 

import javafx.geometry.Insets; 
import javafx.geometry.Pos; 
import javafx.scene.Parent; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.layout.VBox; 

public class Gui { 

    @Inject 
    private Service service ; 

    private VBox view ; 
    private Label label ; 

    public Gui() { 
     Button button = new Button("Press for confirmation"); 
     label = new Label(); 
     label.setVisible(false); 
     button.setOnAction(e -> label.setVisible(true)); 

     view = new VBox(5, label, button); 
     view.setPadding(new Insets(20)); 
     view.setAlignment(Pos.CENTER); 
    } 

    @PostConstruct 
    private void init() { 
     label.setText(service.confirmationMessage()); 
    } 

    public Parent getView() { 
     return view ; 
    } 
} 

最後に、Applicationクラス、Main.java。これは実際にGUIの仕事をしません。アプリケーションのライフサイクルを管理するだけです。ApplicationContextを作成し、メインビューを表すBeanを取得し、それをプライマリステージに表示します。すべての実際のGUI作業は、MainViewクラスに委譲され、そのインスタンスはSpringによって管理されます。それはプレゼンテーション層のための完全なMVC/MVPのデザインを使用するように

import org.springframework.context.annotation.AnnotationConfigApplicationContext; 
import org.springframework.context.support.AbstractApplicationContext; 

import javafx.application.Application; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class Main extends Application { 

    private AbstractApplicationContext context ; 

    @Override 
    public void start(Stage primaryStage) { 
     context = new AnnotationConfigApplicationContext(AppConfig.class); 
     Parent mainView = context.getBean(Gui.class).getView(); 
     primaryStage.setScene(new Scene(mainView)); 
     primaryStage.show(); 
    } 

    @Override 
    public void stop() { 
     context.close(); 
    } 

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

あなたがしたい場合など

+0

おかげで、FXMLを使用して、このアプローチを拡張することができます!私はこれがクラスの責任を分かち合う良い方法だと思います。 – Basti

関連する問題