0

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

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

这是一个非常短的代码片段:

启动应用程序

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");
    }
}

无论我做什么,此代码将始终返回“配置禁用监控”。

像文档中描述的那样直接访问配置也不是一个真正的选项,因为该onStartup方法永远不会被触发。

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

4

1 回答 1

2

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

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

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

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

完整的CDI 教程超出了本问答的范围,但是,切入正题,这里有一种方法。我不得不做出各种假设,比如你想像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();
  }

}
于 2020-11-13T20:57:38.827 回答