Actually, it's the Nth decoction, but ... I mean, it may not be the best practice because I had tried and errored when there was no this article. not.
MainApp.java
/**
*Startup class
* @author ysrken
*/
@ComponentScan
public class MainApp extends Application {
private static ConfigurableApplicationContext context;
/**
*main function
* @param args command line arguments
* @throws Exception Run-time exception
*/
public static void main(String[] args) throws Exception {
//Since this context will be reused in the future, I dared to make it a static variable as described above.
context = new AnnotationConfigApplicationContext(MainApp.class);
launch(args);
}
/**
*JavaFX startup process
* @param stage Stage information
* @throws Exception Run-time exception
*/
public void start(Stage stage) throws Exception {
//It is generated safely, but the point is that it is 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();
}
/**
*Used to route the ApplicationContext
* @return Shared ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return context;
}
/**
*JavaFX termination process
* @throws Exception Run-time exception
*/
@Override
public void stop() throws Exception {
context.close();
}
}
The important part here is " ConfigurableApplicationContext context
", which is used bygetApplicationContext ()
when creating other windows.
In other words, when using FXMLLoader
, set the context asloader.setControllerFactory (MainApp.getApplicationContext () :: getBean);
instead of just doingnew FXMLLoader ()
. This will extend the Spring Framework DI to the window's Controller
and Model
.
Controller.java
@Component
//@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class Controller{
/**
* Model
*/
@Autowired
Model model;
/**
*Initialization
*/
public void initialize() {
~~~
}
}
By setting the context as described above, the Model will be loaded just by @Autowired
. If you plan to create multiple Controllers and Models, uncomment the SCOPE_PROTOTYPE
specification.
Model.java
@Component
//@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class Model{
/**
*Initialization
*/
publicModel() {
~~~
}
}
I'm glad that @Autowired
works even in Model.
I think that the class you want to DI has @Component
etc., but when you create an instance of a class that uses @ Autowired
inside other than the above Controller relation, write as follows. Let's go.
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();
-Create your own FXMLLoader to inject SpringBean
Recommended Posts