在 JakartaEE / Helidon / Microprofile 中手动实例化 类 使用 ConfigProperty
Using ConfigProperty in manually instantiated classes in JakartaEE / Helidon / Microprofile
我在 Helidon start 中有一个小应用程序。它主要是一个 REST 接口,但我也想在启动时启动一些后台监控/日志记录。
我希望通过配置激活/停用该监控。
我面临的问题是,如果我的 class 是手动实例化的,则配置不会被拾取。
这是一个非常短的代码片段:
正在启动应用程序
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");
}
}
无论我做什么,此代码总是 return“配置禁用监控”。
直接访问配置 like described in the documentation 也不是真正的选择,因为永远不会触发 onStartup
方法。
在我的服务器中注入 class 以便它可以根据需要访问配置的正确方法是什么?
你的问题其实是关于CDI的。
为了使任何类型的依赖注入都能与 CDI 一起工作,CDI 必须实例化要注入的东西。在这种情况下,you 实例化要注入的东西,因此 CDI 永远不会“看到”它,因此它永远不会被注入。
我在这里推测,但我猜你的用例真的只是:“我希望我的 CellarMonitoring
组件在 CDI 出现时得到通知。我该怎么做?”。 =14=]
这个问题在这个网站和其他地方有很多答案。本质上,您利用了 CDI 将触发一个事件,通知任何感兴趣的侦听器初始化应用程序范围这一事实。应用范围实际上是应用本身的生命周期,因此您可以将其视为启动事件。
A 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();
}
}
我在 Helidon start 中有一个小应用程序。它主要是一个 REST 接口,但我也想在启动时启动一些后台监控/日志记录。
我希望通过配置激活/停用该监控。 我面临的问题是,如果我的 class 是手动实例化的,则配置不会被拾取。
这是一个非常短的代码片段:
正在启动应用程序
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");
}
}
无论我做什么,此代码总是 return“配置禁用监控”。
直接访问配置 like described in the documentation 也不是真正的选择,因为永远不会触发 onStartup
方法。
在我的服务器中注入 class 以便它可以根据需要访问配置的正确方法是什么?
你的问题其实是关于CDI的。
为了使任何类型的依赖注入都能与 CDI 一起工作,CDI 必须实例化要注入的东西。在这种情况下,you 实例化要注入的东西,因此 CDI 永远不会“看到”它,因此它永远不会被注入。
我在这里推测,但我猜你的用例真的只是:“我希望我的 CellarMonitoring
组件在 CDI 出现时得到通知。我该怎么做?”。 =14=]
这个问题在这个网站和其他地方有很多答案。本质上,您利用了 CDI 将触发一个事件,通知任何感兴趣的侦听器初始化应用程序范围这一事实。应用范围实际上是应用本身的生命周期,因此您可以将其视为启动事件。
A 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();
}
}