En fait, c'est la Nième décoction, mais ce n'est peut-être pas la meilleure pratique car c'était un essai et une erreur au stade où il n'y avait pas cet article. ne pas.
MainApp.java
/**
 *Classe de démarrage
 * @author ysrken
 */
@ComponentScan
public class MainApp extends Application {
    private static ConfigurableApplicationContext context;
    
    /**
     *fonction principale
     * @param args arguments de ligne de commande
     * @jette une exception d'exécution d'exception
     */
    public static void main(String[] args) throws Exception {
        //Puisque ce contexte sera réutilisé dans le futur, j'ai osé en faire une variable statique comme décrit ci-dessus.
    	context = new AnnotationConfigApplicationContext(MainApp.class);
        launch(args);
    }
    /**
     *Processus de démarrage JavaFX
     * @param stage Informations sur la phase
     * @jette une exception d'exécution d'exception
     */
    public void start(Stage stage) throws Exception {
        //Il est généré en toute sécurité, mais le fait est qu'il s'agit de getBean
        FXMLLoader loader = new FXMLLoader();
        loader.setControllerFactory(MainApp.getApplicationContext()::getBean);
        Parent rootNode = (Parent) loader.load(getClass().getResourceAsStream("/fxml/MainView.fxml"));
        Scene scene = new Scene(rootNode);
        stage.setScene(scene);
        mainStage.show();
    }
    
    /**
     *Utilisé pour acheminer le ApplicationContext
     * @return Shared ApplicationContext
     */
    public static ApplicationContext getApplicationContext() {
    	return context;
    }
    
    /**
     *Traitement de fin de JavaFX
     * @jette une exception d'exécution d'exception
     */
    @Override
    public void stop() throws Exception {
        context.close();
    }
}
La partie importante ici est " ConfigurableApplicationContext context", qui est utilisé par getApplicationContext () lors de la création d'autres fenêtres.  En d'autres termes, lorsque vous utilisez FXMLLoader, définissez le contexte comme loader.setControllerFactory (MainApp.getApplicationContext () :: getBean); ʻau lieu de simplement faire new FXMLLoader (). En faisant cela, la DI du Spring Framework s'étend au "Controller" et au "Model" de la fenêtre.
Controller.java
@Component
//@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class Controller{
    /**
     * Model
     */
    @Autowired
    Model model;
    /**
     *Initialisation
     */
    public void initialize() {
        ~~~
    }
}
En définissant le contexte comme décrit ci-dessus, le modèle sera chargé uniquement par @ Autowired. Si vous prévoyez de créer plusieurs contrôleurs et modèles, supprimez les commentaires de la spécification SCOPE_PROTOTYPE.
Model.java
@Component
//@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class Model{
    /**
     *Initialisation
     */
    publicModel() {
        ~~~
    }
}
Je suis content que @ Autowired fonctionne même dans Model.
Je pense que la classe que vous voulez DI a @ Component etc., mais lorsque vous créez une instance d'une classe qui utilise @ Autowired à l'intérieur autre que la relation Controller ci-dessus, écrivez comme suit. Allons-y.
sample.java
@Component
public class SampleClass {
    /**
     * Model
     */
    @Autowired
    Hoge hoge;
    ~~~~~~
}
// OK
final SampleClass x = MainApp.getApplicationContext().getBean(SampleClass.class);
// NG
final SampleClass y = new SampleClass();
Recommended Posts