【问题标题】:Using ConfigProperty in manually instantiated classes in JakartaEE / Helidon / Microprofile在 JakartaEE / Helidon / Microprofile 的手动实例化类中使用 ConfigProperty
【发布时间】:2020-11-11 10:47:40
【问题描述】:

我在 Helidon start 中有一个小应用程序。它主要是一个REST接口,但我也想在启动时启动一些后台监控/日志记录。

我希望通过配置激活/停用该监控。 我面临的问题是,如果我的类是手动实例化的,则配置不会被拾取。

这是一个很短的代码 sn-p :

启动应用程序

public class Main {

    private Main() { }

    public static void main(final String[] args) throws IOException {
        Server server = startServer();

        CellarMonitoring monitoring = new CellarMonitoring();
        monitoring.start();
    }

    static Server startServer() {
        return Server.create().start();
    }
}

是否启动监控基于配置:

package nl.lengrand.cellar;

import org.eclipse.microprofile.config.inject.ConfigProperty;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;

public class CellarMonitoring {

    @Inject
    @ConfigProperty(name = "monitoring.enabled", defaultValue = "true")
    private volatile boolean monitoringEnabled; <= Always false

    public void start(){
        if(monitoringEnabled) {
            System.out.println("Monitoring enabled by config. Starting up");
        }
        else System.out.println("Monitoring disabled by config");
    }
}

无论我做什么,这段代码都会返回“监控被配置禁用”。

直接访问配置 like described in the documentation 也不是一个真正的选项,因为永远不会触发 onStartup 方法。

在我的服务器中注入一个类以便它可以根据需要访问配置的正确方法是什么?

【问题讨论】:

    标签: java jakarta-ee helidon


    【解决方案1】:

    您的问题实际上是关于 CDI。

    为了使任何类型的依赖注入能够与 CDI 一起使用,CDI 必须实例化要注入的事物。在这种情况下,实例化要注入的东西,所以 CDI 永远不会“看到”它,所以它永远不会被注入。

    我在这里推测,但我猜您的用例实际上只是:“我希望在 CDI 出现时通知我的 CellarMonitoring 组件。我该怎么做?”

    在这个网站和其他地方有很多关于这个问题的答案。本质上,您利用了 CDI 将在应用程序范围的初始化中触发一个事件来通知任何感兴趣的侦听器这一事实。应用范围实际上是应用本身的生命周期,因此您可以将其视为启动事件。

    full CDI tutorial 超出了本问答的范围,但是,切入正题,这里有一种方法。我不得不做出各种假设,例如您希望 CellarMonitoring 像单身人士一样:

    @ApplicationScoped
    public class CellarMonitoring {
    
      @Inject
      @ConfigProperty(name = "monitoring.enabled", defaultValue = "true")
      private volatile boolean monitoringEnabled; // <= Always false
    
      public void start() {
        if (monitoringEnabled) {
          System.out.println("Monitoring enabled by config. Starting up");
        } else {
          System.out.println("Monitoring disabled by config");
        }
      }
    
      private void onStartup(@Observes @Initialized(ApplicationScoped.class) final Object event) {
        // The container has started.  You can now do what you want to do.
        this.start();
      }
    
    }
    

    【讨论】:

    • 我应该提一下,如果出于某种原因手动实例化是您绝对认为由于某种原因必须执行的操作,此处未详细说明,您可以使用 CDI 的 Unmanaged 类:jakarta.ee/specifications/cdi/3.0/apidocs/jakarta/enterprise/…
    • 您好,非常感谢!你是绝对正确的。在过去的几天里,我一直在深入研究这个话题,事情把我引向了 CDI。这是我通常在现有系统中使用的东西,但应该学会更好地了解。我曾尝试过 onStartup 方法,但缺少 Observes 注释。非常感谢!
    • 看到你在 Helidon 上工作真是太棒了!超级好项目,我真的很喜欢它,因为我之前演示过。
    猜你喜欢
    • 1970-01-01
    • 2023-02-07
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    • 2019-03-07
    • 1970-01-01
    • 2013-05-12
    • 2016-06-08
    相关资源
    最近更新 更多