gpt4 book ai didi

java - 将 guice 与 javafx 和 hibernate 一起使用

转载 作者:行者123 更新时间:2023-12-02 02:24:09 28 4
gpt4 key购买 nike

我有一个看起来像这样的 javafx Controller

public class DictionaryFxController implements Initializable {

@Inject
private QueryTemplate queryTemplate;

@SuppressWarnings("unchecked")
@Override
public void initialize(URL location, ResourceBundle resources) {
....
queryTemplate.insert(langs);
....
}
}

我的application类看起来像这样

public class Main extends Application {

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

@Override
public void start(Stage primaryStage) throws Exception {
Injector injector = Guice.createInjector(new ApplicationModule());
Scene scene = null;
FXMLLoader loader = new FXMLLoader();
try {
Parent root = loader.load(getClass().getResourceAsStream("/dictionary.fxml"));
loader.setControllerFactory(injector::getInstance);
scene = new Scene(root);
} catch (IOException e) {
throw new IllegalStateException(e);
}

primaryStage.setTitle("Dictionary");
primaryStage.setScene(scene);
primaryStage.show();
}

}

我提供 Hibernate session 的类如下所示

@Singleton
public class HibernateController {
private SessionFactory sessionFactory;

public HibernateController() {
sessionFactory = new Configuration()
.configure()
.buildSessionFactory();
}

public Session openSession() {
return sessionFactory.openSession();
}

@PreDestroy
private void close() {
sessionFactory.close();
StandardServiceRegistryBuilder.destroy(sessionFactory.getSessionFactoryOptions().getServiceRegistry());
}
}

我将此类连接到用于执行查询的模板

public class QueryTemplate {
private HibernateController hibernateController;

@Inject
public QueryTemplate(HibernateController controller) {
this.hibernateController = controller;
}

public <T> void insert(List<T> objects) {
try (Session session = hibernateController.openSession()) {
Transaction tx = session.beginTransaction();

// generalize
objects.forEach(session::save);

tx.commit();
}
}
}

我在模块中绑定(bind)了这个类

public class ApplicationModule extends AbstractModule {
@Override
protected void configure() {
bind(QueryTemplate.class);
}
}

但是当我启动应用程序时,它就失败了

   queryTemplate.insert(langs);

因为 queryTemplate 为空。有什么问题吗?

最佳答案

您正在加载 FXML 后设置 Controller 工厂;此时 Controller 已经被创建。由于 FXMLLoader 将使用默认机制来创建 Controller - 即简单地调用 Controller 的默认构造函数 - Controller 不受 Guice 管理,并且不会初始化其注入(inject)字段。

您只需颠倒 loader.setControllerFactory(...)loader.load(...) 的行顺序即可解决该问题。

顺便说一句,设置 FXMLLoader 的位置比使用 load(InputStream) 方法更好。如果您使用采用 Stream 的方法,则不会设置位置,并且位置解析将无法在 FXML 文件中正常工作。

所以替换

    FXMLLoader loader = new FXMLLoader();
try {
Parent root = loader.load(getClass().getResourceAsStream("/dictionary.fxml"));
loader.setControllerFactory(injector::getInstance);
scene = new Scene(root);
} catch (IOException e) {
throw new IllegalStateException(e);
}

    FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/dictionary.fxml"));
loader.setControllerFactory(injector::getInstance);
try {
Parent root = loader.load();
scene = new Scene(root);
} catch (IOException e) {
throw new IllegalStateException(e);
}

您可以将前两行合并为一行

    FXMLLoader loader = new FXMLLoader(getClass().getResource("/dictionary.fxml"));

如果你愿意的话。

关于java - 将 guice 与 javafx 和 hibernate 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48042589/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com