【问题标题】:Spring constructor injection with FXML使用 FXML 的 Spring 构造函数注入
【发布时间】:2016-03-18 07:59:44
【问题描述】:

我已经搜索过答案,但找不到太多。 我发现了什么:http://steveonjava.com/javafx-in-spring-day-2/ 这是一篇关于如何将 spring 用于控制器的好帖子,但它说你不能使用构造函数注入。那不会是那么大的痛苦,只是对我来说不是那么干净。 当我想使用自定义控件(或自定义组件)时出现问题。自定义控件由 javafx 创建,因此不会在 spring 上下文中。

问题在于,对于给定的解决方案,只有控制器会由 spring 创建。我找到了一种可行的方法。感谢https://www.javacodegeeks.com/2012/04/fxml-custom-components-using.html articel。但我想概括该解决方案。所以计划是编写我的自定义 BuilderFactory 和 Builder 实现,这需要大量的反思。

您如何看待这种方法?

欢迎任何想法

【问题讨论】:

  • 看看我的例子here是否有帮助。我在这里使用 Java 配置,它为控制器使用构造函数注入。我尝试使用BuilderFactoryBuilders 使自定义组件成为Spring 管理的bean:它工作得很好。不确定我在任何地方仍然有代码。基本思想是写一个BuilderFactory 来包装默认的JavaFXBuilderFactory。检查传入的类型是否有 spring bean,如果有则返回创建它的构建器,否则委托给默认工厂。没有太多的反思。

标签: spring custom-controls javafx-8 custom-component


【解决方案1】:

您当然可以使用BuilderFactory 来执行此操作。代码一点也不差,因为默认的构建器工厂在公共 API 中实现为JavaFXBuilderFactory。因此,如果应用程序上下文中没有适当类型的 bean,您可以简单地委托给它。

基本上:

private Parent loadFXML(ApplicationContext applicationContext, URL fxmlLocation) 
        throws IOException {
    FXMLLoader loader = new FXMLLoader(fxmlLocation);

    // load controllers from application context:
    loader.setControllerFactory(applicationContext::getBean);

    // load controls from application context, where available:
    loader.setBuilderFactory(new BuilderFactory() {
        JavaFXBuilderFactory defaultFactory = new JavaFXBuilderFactory();

        @Override
        public javafx.util.Builder<?> getBuilder(Class<?> type) {
            String[] beanNames = applicationContext.getBeanNamesForType(type);
            if (beanNames.length == 1) {
                return new javafx.util.Builder<Object>() {

                    @Override
                    public Object build() {
                        return applicationContext.getBean(beanNames[0]);
                    }

                };
            } else {
                return defaultFactory.getBuilder(type) ;
            }
        }
    });

    return loader.load();
}

【讨论】:

  • 感谢您的评论。我打算做这样的事情。但是您是否使用 @FXML 注释测试过这个解决方案?我做了类似的事情,但效果不佳,因为 builder 没有参数方法。我会试试你的解决方案。如我所见,您没有在项目中使用自定义控件。我见过很多控制器。我想用处理程序创建自定义事件,这些事件应该由 java fx 注入
  • 嗯。不完全确定你的意思。我想如果您希望控件是弹簧管理的 bean,您将使用 Spring 注入来初始化它们,而不是在 FXML 中初始化它们。 @FXML 注入工作得很好,FXMLLoader 从控制器工厂中指定的任何位置(即在本例中为 Spring)获取控制器类,然后从 fx:ids 注入 @FXML-annotated 字段以通常的 JavaFX 方式。我根本没有使用自定义事件。也许在您的问题中发布一些代码来显示您想要做什么?
  • 抱歉这么慢,但我不得不检查您的解决方案。不幸的是,我无法完成这项工作。你能检查一下我做错了什么吗?你可以在这里找到我的示例:github.com/gege83/javafxCustomComponenetWithSpring
  • 好的,所以那里有很多错误。我确实让它工作了,只是一个一个地检查和修复它们。这里的文档太多了,但首先要修复 Spring 配置,然后修复 MyCustomControl.fxml 以便使用 &lt;fx:root&gt; (并且只修复明显的 XML 错误);在MyCustomControl.java 中,如前所述,您需要使用标准FXMLLoader,而不是SpringFXMLLoader,并遵循自定义控制模式。我从 Maven 配置中取出了所有 zenjava 的东西。
  • 拳头我想对我提交给你的那个setti工作表示抱歉。最后我设法工作了,我将把那个存储库作为参考。再次感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多