在 JavaFX (JPA Repo, Service) 中添加 Spring 依赖注入

如何解决在 JavaFX (JPA Repo, Service) 中添加 Spring 依赖注入

有许多方法可以将依赖项注入到 JavaFX 应用程序中。例如,Gluon 有一个名为Gluon Ignite的项目,它为各种依赖注入框架(如 Guice、Spring 和 Dagger)启用 JavaFX 应用程序。

由于您选择了 Spring 作为依赖注入框架,并且希望使用一系列其他 Spring 工具,例如 Spring Data 存储库,因此您可能希望考虑使用 SpringBoot 应用程序。

您可以使您的 JavaFX 应用程序成为 SpringBoot 应用程序(尽管这对于获取依赖项注入并不是绝对必要的),以便在您的应用程序中获得一堆可用的 Spring 工具。

该示例的关键部分是应用程序的 init() 方法(我刚刚复制并粘贴并复制到此处以供参考):

@SpringBootApplication
public class DemoApplication extends Application {

    private ConfigurableApplicationContext springContext;
    private Parent root;

    @Override
    public void init() throws Exception {
        springContext = SpringApplication.run(DemoApplication.class);
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/sample.fxml"));
        fxmlLoader.setControllerFactory(springContext::getBean);
        root = fxmlLoader.load();
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Hello World");
        Scene scene = new Scene(root, 800, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    @Override
    public void stop() throws Exception {
        springContext.stop();
    }


    public static void main(String[] args) {
        launch(DemoApplication.class, args);
    }
}

示例应用程序正在运行 SpringBoot 应用程序以启动 Spring 系统并让它在 init 方法中提供应用程序上下文。然后应用程序使用 FXMLLoadersetControllerFactory()方法允许 Spring 实例化 FXML 控制器并在应用程序中注入对 Spring bean 的引用。

要让您的 JAVAFX FXML 控制器自动装配,除了以下调用 FXMLLoader 之外:

fxmlLoader.setControllerFactory(springContext::getBean);

您还需要将您的类注释为 Spring @Component,并且@Autowired在您希望控制器使用的任何 Spring 依赖项中。通过这种方式,FXMLLoader 将基于 @FXML 的引用注入到您的 UI 元素,它还将委托给 spring 上下文以注入 Spring 依赖项。

@Component
public class DemoController {
    @FXML
    private Label usernameLabel; 

    @Autowired
    public SpringService mySpringService;

    public void initialize() {
        usernameLabel.setText(
            mySpringService.getLoggedInUsername()
        );
    }
}

请注意,Spring 有一个@Controller注解,可用于注解 JavaFX 控制器而不是@Component注解,但我建议避免将其@Controller用于此目的,而是将@Controller注解用于 Spring REST 服务端点控制器定义。

您可能需要注意的一件事是,运行 SpringBoot 应用程序会生成一个新的应用程序实例,并且您已经拥有一个由 JavaFX 系统启动的 JavaFX 应用程序实例,因此如果 SpringBoot 应用程序会产生两个 JavaFX 应用程序实例和 JavaFX 应用程序基于相同的类(如上所示),这可能会造成混淆。

因此,将 Spring 应用程序和 JavaFX 应用程序分开可能会更好。这增强了应用程序的 UI 和服务部分之间的关注点分离,并使测试更容易,因为 Spring 应用程序可以独立于启动和关闭 JavaFX 应用程序进行单元测试。

注意,使用上述设置,它不会自动装配 JavaFX 应用程序类实例化实例。如果您希望这样做,您可以使用下面说明的技术在 JavaFX 实例化的应用程序类中注入 bean:

将以下代码放在应用程序的 init 方法中:

springContext
    .getAutowireCapableBeanFactory()
    .autowireBeanProperties(
        this,
        AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, 
        true
    );

mvvmFX框架使用与上述类似的方法将 SpringBoot 与 JavaFX 应用程序集成:

要将参数从 JavaFX 应用程序传递到 SpringBoot 应用程序,请使用:

SpringApplication.run(
    DemoApplication.class, 
    getParameters().getRaw().toArray(new String[0])
);

如果您需要对 SpringApplication 的启动进行更多控制,您可以使用 SpringApplicationBuilder 例如:

ConfigurableApplicationContext startupContext =
        new SpringApplicationBuilder(DemoApplication.class)
                .web(WebApplicationType.NONE)
                .run(args);

这个答案只是为了给你一些关于如何解决这个问题的提示,而不是作为关于如何将依赖注入与 JavaFX 集成的通用指南,这可能最终成为一个非常棘手的主题,需要全面涵盖。

解决方法

我有一个 java FX 基本应用程序,它有一个简单的场景(一个表单)。我有一个 Mysql Db,我正在使用 Spring JPA(spring data jpa 即存储库/实体)与之交互。

现在,因为我们知道 javaFx 有一些生命周期钩子,即:init() start() 和 stop()。

假设我想使用 JPA save()方法在数据库中插入数据。通常,如果它是我的控制器,正常的数据库注入,如:

@Autowired
EmployeeRepo employeeRepo;

本来可以的。但是,我无法在生命周期方法中访问它(或任何自动装配注入)。

public void start(Stage primaryStage) throws Exception {

// Some Code

employeeRepo.findAll() <- This is returning null

但是,当我添加测试方法并使用相同的方法时,它可以正常工作:

@PostConstruct
public void test() {
// Repo object is not giving null
}

有没有办法可以在按钮侦听器中手动注入依赖项或将其传递给启动方法。

请让我知道是否有解决方案,因为我是 JavaFX 新手

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-