You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在QuarkusTestResourceLifecycleManager中注入Arc Bean及加载配置?

问题:QuarkusTestResourceLifecycleManager中无法获取Arc Bean及配置源问题

核心疑问

我尝试实现QuarkusTestResourceLifecycleManager,想在其中注入/查找Arc中的Bean,但始终失败。代码示例如下:

public class FlywayTestResource implements QuarkusTestResourceLifecycleManager {

    @Override
    public Map<String, String> start() {
        Flyway flyway = Arc.container().instance(Flyway.class).get(); // 此处执行失败
        // ...
    }
}

请问是不是根本无法在此处注入Bean?是不是因为此时Quarkus Arc还未初始化?

更新1:配置源异常

发现ConfigProvider.getConfig()的配置源中不包含application.properties。

更新2:临时方案的困扰

有一种“脏 hack”是把application.properties内容复制到系统属性,但我认为这种方式非常不雅。有没有更规范简便的方法将application.properties添加到配置源?临时方案代码如下:

public void loadApplicationProperties() {
        Properties properties = new Properties();

        String path = this.getClass().getClassLoader().getResource("application.properties").getPath();

        try (FileInputStream input = new FileInputStream(path)) {
            properties.load(input);

            for (String key : properties.stringPropertyNames()) {
                String value = properties.getProperty(key);
                System.setProperty(key, value);
            }

            System.out.println("Properties copied to environment variables successfully.");
        } catch (IOException e) {
           
        }
    }

解答

关于Arc Bean无法获取的问题

是的,在QuarkusTestResourceLifecycleManager的start()方法中确实无法直接获取Arc容器中的Bean。原因在于Quarkus的测试启动流程里,QuarkusTestResourceLifecycleManager是在Arc容器初始化之前执行的——它的核心作用是为测试提前准备外部依赖(比如数据库、消息队列等),此时应用上下文还未启动,Arc容器自然也没有完成初始化,所以无法通过Arc.container()获取任何Bean实例。

如果你的场景是要在测试资源中使用Flyway执行数据库迁移,可以换两种思路:

  • 手动初始化Flyway实例:不依赖Arc注入,直接通过读取配置(系统属性、环境变量或手动加载配置文件)获取数据库连接信息,自行构建Flyway对象。
  • 使用官方Flyway扩展测试支持:Quarkus官方的Flyway扩展会自动在测试启动时执行迁移,无需自定义QuarkusTestResourceLifecycleManager。

关于添加application.properties到配置源的问题

不推荐使用复制系统属性的“脏 hack”,Quarkus提供了更规范的方式:

方法1:用Quarkus Config API手动加载配置源

通过ConfigProviderResolver手动添加配置源,符合Quarkus配置体系,不会污染系统属性:

public void loadApplicationProperties() {
    try {
        URL resource = Thread.currentThread().getContextClassLoader().getResource("application.properties");
        if (resource != null) {
            PropertiesConfigSource configSource = new PropertiesConfigSource(
                new File(resource.toURI()), 
                "application.properties", 
                ConfigSource.DEFAULT_ORDINAL
            );
            ConfigProviderResolver.instance().getBuilder()
                .addSources(configSource)
                .build();
        }
    } catch (URISyntaxException | IOException e) {
        // 处理异常逻辑
    }
}

方法2:利用TestResource返回配置映射

在QuarkusTestResourceLifecycleManager的start()方法中返回配置键值对,这些配置会被Quarkus配置系统优先加载,效果和读取application.properties一致,更符合组件设计初衷:

@Override
public Map<String, String> start() {
    Map<String, String> testConfig = new HashMap<>();
    // 示例:添加数据库连接、Flyway启动配置
    testConfig.put("quarkus.datasource.jdbc.url", "jdbc:h2:mem:testdb");
    testConfig.put("quarkus.flyway.migrate-at-start", "true");
    return testConfig;
}

内容的提问来源于stack exchange,提问作者syr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 07:37:29