java - FXML 加载器不创建新实例

标签 java javafx spring-boot fxml fxmlloader

我有一个 JavaFX + Spring Boot 应用程序。当我尝试使用其 Controller 加载新的 FXML 时,它工作正常,但是当我第二次或第三次加载它时,它会为我提供相同的实例,并且不会创建新的实例。

我的 FXML 加载器如下:

public <T> T loadAndGetController(String fxmlPath) throws IOException {
    FXMLLoader loader = new FXMLLoader();
    loader.setControllerFactory(context::getBean); // Spring now FXML Controller Factory
    loader.setLocation(getClass().getResource(fxmlPath));
    loader.setResources(ResourceBundle.getBundle("language/lang",
            new Locale(languageController.getLanguage().getValue(), languageController.getLanguage().toString())));
    loader.load();
    return loader.getController();
}

加载新的 FXML:

TabController tabController = (TabController) StageManager.loadAndGetController(FXMLViews.TAB.getFxmlFile());

当我尝试将其添加到加载的 Controller 列表中时,ID 与哈希码相同,这意味着它是同一个实例。因此它没有创建一个新的。

enter image description here

也许我加载的 FXML 是错误的,或者只是 Spring-Boot Controller 工厂在这种情况下工作得很奇怪。有什么建议吗?

最佳答案

线路

loader.setControllerFactory(context::getBean);

指示FXMLLoader从Spring应用程序上下文中获取 Controller :在内部,FXMLLoader现在将执行类似的操作

Class controllerClass = Class.forName(classNameFromFXMLFile);
Object controller = context.getBean(controllerClass);

getBean 的行为取决于您如何为该类配置 bean,但默认情况下它将具有“单例”范围。这意味着它将创建该类的一个实例,并在每次使用映射到该 bean 的参数(例如 bean 的类)调用 getBean(...) 时返回相同的实例。

每次加载 FXML 文件时,几乎肯定需要一个 Controller 类的新实例,因此您应该将 bean 配置为具有“原型(prototype)”范围。在“原型(prototype)”范围内,每次都会创建一个新实例。

定义 bean 范围的机制取决于您如何配置应用程序上下文,但使用基于注释的配置,您会执行类似的操作

@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class FarTabController { /* ... */ }

使用基于 Java 的配置即可

@Configuration
public class ApplicationConfig {

    @Bean
    @Scope(BeanDefinition.SCOPE_PROTOTYPE)
    public FarTabController farTabController() {
        return new FarTabController() ;
    }

    // ...
}

如果您仍在使用旧的基于模式(XML)的配置,您会这样做(如果我没记错的话)

<beans>

    <bean class="my.package.FarTabController" scope="prototype" />

    <!-- ... -->

</beans>

关于java - FXML 加载器不创建新实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43392743/

相关文章:

user-interface - JavaFX CSS : How to set tabpane tabs - width, 高度

java - 从 JavaFX 2.2 升级到 JavaFX 8 的问题(可能是错误?)

mysql - Java 应用程序在亚马逊 AWS 中运行一段时间后停止运行

java - 使用 Sax 解析大型 XML 文件

java - 将 JavaFX WebView 调整为文档正文所需的最小大小

java - 获取登录用户的详细信息

spring-boot - java.lang.NoSuchMethodError : org. mockito.MockingDetails.getMockCreationSettings() - Gradle 为 Mockito jar 链接同一个类两次

java - Java equals 方法的良好设计

java - 如何使用 Maven 和 Intellij IJ idea 编译并启动 Javafx 应用程序?

spring-boot - 无法在单元测试中 Autowiring 存储库(多模块 Maven 项目)