依赖注入和JavaFX
由于JavaFX运行时希望实例化我的应用程序对象和所有控制器对象,因此如何将依赖项注入这些对象 如果对象由DI框架(如Spring)实例化,该框架将连接所有依赖项。如果我手动实例化对象,我将通过构造函数参数提供依赖项。但是在JavaFX应用程序中我该怎么做呢 谢谢 您可以为依赖注入和JavaFX,java,javafx,dependency-injection,Java,Javafx,Dependency Injection,由于JavaFX运行时希望实例化我的应用程序对象和所有控制器对象,因此如何将依赖项注入这些对象 如果对象由DI框架(如Spring)实例化,该框架将连接所有依赖项。如果我手动实例化对象,我将通过构造函数参数提供依赖项。但是在JavaFX应用程序中我该怎么做呢 谢谢 您可以为FXMLLoader指定一个。控制器工厂是一个将控制器类映射到将用作控制器的对象(可能是,但不一定是该类的实例)的函数 因此,如果您希望Spring为您创建控制器实例,这可以非常简单: ApplicationContext c
FXMLLoader
指定一个。控制器工厂是一个将控制器类映射到将用作控制器的对象(可能是,但不一定是该类的实例)的函数
因此,如果您希望Spring为您创建控制器实例,这可以非常简单:
ApplicationContext context = ... ;
FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/fxml"));
loader.setControllerFactory(context::getBean);
Parent root = loader.load();
SomeController controller = loader.getController(); // if you need it...
// ...
现在,fxmloader
将通过调用context.getBean(c)为类c
创建控制器实例代码>
例如,您可以有一个配置:
@Configuration
public class AppConfig {
@Bean
public MyService service() {
return new MyServiceImpl();
}
@Bean
@Scope("prototype")
public SomeController someController() {
return new SomeController();
}
// ...
}
与
如果您不使用DI框架,并且您想“手工”进行注入,那么您可以这样做,但这涉及到使用大量反射。以下内容展示了Spring是如何(并将让您了解Spring为您做了多少丑陋的工作!):
最后,您可能想检查一下,这是一个非常轻量级(以所有最佳方式)的JavaFX特定DI框架。(它使用了一种约定优于配置的方法,您只需将FXML文件名与控制器类名匹配,还可以选择CSS文件名,一切正常。)我使用FXMLLoader类的setControllerFactory方法来设置此序列化程序使用的控制器工厂
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.refresh();
FXMLLoader loader = new FXMLLoader(getClass().getResource("../view/sample.fxml"));
loader.setControllerFactory(ctx::getBean);
Parent root = loader.load();
Controller controller = loader.getController();
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 925, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
然后使用@component创建控制器类
@Component
public class Controller {
@Autowired
private ItemController itemController;
@FXML
private TextField item;
@FXML
private TextField quantity;
}
public class SomeController {
private final MyService service ;
public SomeController(MyService service) {
this.service = service ;
}
// injected by FXMLLoader:
@FXML
private TextField someTextField ;
public void initialize() {
someTextField.setText(service.getSomeText());
}
// event handler:
@FXML
private void performAction(ActionEvent e) {
service.doAction(...);
}
}
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext();
ctx.register(AppConfig.class);
ctx.refresh();
FXMLLoader loader = new FXMLLoader(getClass().getResource("../view/sample.fxml"));
loader.setControllerFactory(ctx::getBean);
Parent root = loader.load();
Controller controller = loader.getController();
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 925, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
@Component
public class Controller {
@Autowired
private ItemController itemController;
@FXML
private TextField item;
@FXML
private TextField quantity;
}