在javafx和hibernate中使用guice
我有一个在javafx和hibernate中使用guice,java,hibernate,javafx-8,guice,Java,Hibernate,Javafx 8,Guice,我有一个javafx控制器,看起来像这样 public class DictionaryFxController implements Initializable { @Inject private QueryTemplate queryTemplate; @SuppressWarnings("unchecked") @Override public void initialize(URL location, ResourceBundle resour
javafx
控制器,看起来像这样
public class DictionaryFxController implements Initializable {
@Inject
private QueryTemplate queryTemplate;
@SuppressWarnings("unchecked")
@Override
public void initialize(URL location, ResourceBundle resources) {
....
queryTemplate.insert(langs);
....
}
}
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();
}
}
@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 DictionaryFxController implements Initializable {
@Inject
private QueryTemplate queryTemplate;
@SuppressWarnings("unchecked")
@Override
public void initialize(URL location, ResourceBundle resources) {
....
queryTemplate.insert(langs);
....
}
}
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();
}
}
@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());
}
}
我的类提供了Hibernate
会话,如下所示
public class DictionaryFxController implements Initializable {
@Inject
private QueryTemplate queryTemplate;
@SuppressWarnings("unchecked")
@Override
public void initialize(URL location, ResourceBundle resources) {
....
queryTemplate.insert(langs);
....
}
}
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();
}
}
@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();
}
}
}
但当我启动应用程序时,它在线路上失败了
queryTemplate.insert(langs);
因为queryTemplate
为空。
问题是什么?加载FXML后,您正在设置控制器出厂设置;此时已创建控制器。由于fxmloader
将使用默认机制创建控制器-即简单地调用控制器的默认构造函数-控制器不由Guice管理,并且不会初始化其注入字段
只需使用loader.setControllerFactory(…)
和loader.load(…)
颠倒行的顺序,即可解决此问题
另外,设置fxmloader
的位置比使用load(InputStream)
方法更好。如果使用获取流的方法
,则不会设置位置,并且在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(getClass().getResource("/dictionary.fxml"));
如果愿意。加载FXML后,您正在设置控制器工厂;此时已创建控制器。由于fxmloader
将使用默认机制创建控制器-即简单地调用控制器的默认构造函数-控制器不由Guice管理,并且不会初始化其注入字段
只需使用loader.setControllerFactory(…)
和loader.load(…)
颠倒行的顺序,即可解决此问题
另外,设置fxmloader
的位置比使用load(InputStream)
方法更好。如果使用获取流的方法
,则不会设置位置,并且在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(getClass().getResource("/dictionary.fxml"));
如果你愿意的话