启动 Micronaut 应用程序时如何打印环境变量
How to print out environment variables, when starting a Micronaut application
我正在做一个 Micronaut 项目,我想看看当应用程序在本地启动时,来自 application.yml 的环境变量是否使用 @Value 注释正确分配。
但是每次应用程序启动时,它都会显示变量没有分配给 application.yml 文件中的环境变量。
这是我的代码:
public class Application {
private static String localTestString = "I am the local String";
@Value("${aws.secretkeyid}")
public static String applicationYmlTestString;
@Value("${aws.keyid}")
private static int keyId;
public static void main(String[] args) {
Micronaut.run(Application.class);
}
static{
log.warn("Local Test String is: " + localTestString);
log.warn("Application Yml Test String is: " + applicationYmlTestString);
log.warn("Key ID: " + keyId);
}
}
这是我的application.yml
aws:
keyid: 123
secretkeyid: "abcdesdasdsddddd"
region: "europe-1"
输出:
Local Test String is: I am the local String
Application Yml Test String is: null
Key ID: 0
我们看到两个变量 applicationYmlTestString 和 keyId 没有被分配给环境变量。有没有办法解决这个问题并得到:
Application Yml Test String is: abcdesdasdsddddd
Key ID: 123
提前致谢!
您展示的示例存在两个问题。首先,Micronaut 不会向用 @Value
注释注释的静态字段 注入值。 (这并不奇怪,Spring does not support it as well。)其次,在向 non-static 字段注入值后,您将无法使用 class' 静态构造函数读取它们的值。整个应用程序上下文必须准备好读取这些值,因此您需要使用对应用程序启动事件做出反应的事件侦听器。
根据您的示例,这是实现它的最简单方法:
package micronaut.hello.world;
import io.micronaut.context.annotation.Value;
import io.micronaut.context.event.StartupEvent;
import io.micronaut.runtime.Micronaut;
import io.micronaut.runtime.event.annotation.EventListener;
import jakarta.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
@Value("${aws.secretkeyid}")
private String applicationYmlTestString;
@Value("${aws.keyid}")
private int keyId;
public static void main(String[] args) {
Micronaut.run(Application.class, args);
}
@EventListener
void onStartup(StartupEvent event) {
log.warn("Application Yml Test String is: " + applicationYmlTestString);
log.warn("Key ID: " + keyId);
}
public String getApplicationYmlTestString() {
return applicationYmlTestString;
}
public void setApplicationYmlTestString(String applicationYmlTestString) {
this.applicationYmlTestString = applicationYmlTestString;
}
public int getKeyId() {
return keyId;
}
public void setKeyId(int keyId) {
this.keyId = keyId;
}
}
有三点值得一提:
- 上面的例子使用了
@EventListener
注解,使给定的方法成为“event-aware”,这个方法将在应用程序(或框架)发布特定事件时被触发。
- 我们响应
io.micronaut.context.event.StartupEvent
- 启动完成后触发的事件。
- 请记住,要使此
@EventListener
注释起作用,我们需要使用 @Singleton
注释应用程序 class 以使此 class 成为合适的 Micronaut bean。
或者,如果使应用程序 class 单例 bean 对您来说不合适,您可以实现 ApplicationEventListener
接口并创建一个专用 bean 来响应相同的启动事件。在这个例子中,我使用了一个静态内部class,但这只是为了让这个例子简单:
package micronaut.hello.world;
import io.micronaut.context.annotation.Value;
import io.micronaut.context.event.ApplicationEventListener;
import io.micronaut.context.event.StartupEvent;
import io.micronaut.runtime.Micronaut;
import jakarta.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
Micronaut.run(Application.class, args);
}
@Singleton
static class OnStartupEventListener implements ApplicationEventListener<StartupEvent> {
@Value("${aws.secretkeyid}")
private String applicationYmlTestString;
@Value("${aws.keyid}")
private int keyId;
@Override
public void onApplicationEvent(StartupEvent event) {
log.warn("Application Yml Test String is: " + applicationYmlTestString);
log.warn("Key ID: " + keyId);
}
public String getApplicationYmlTestString() {
return applicationYmlTestString;
}
public void setApplicationYmlTestString(String applicationYmlTestString) {
this.applicationYmlTestString = applicationYmlTestString;
}
public int getKeyId() {
return keyId;
}
public void setKeyId(int keyId) {
this.keyId = keyId;
}
}
}
但最终,您应该考虑实现配置 class 并使用它而不是使用 @Value
注释注入值。但是,无论您选择什么选项,同样的事情都适用 - 配置 class 可以注入到 non-static 字段,并且可以使用事件侦听器机制进行检查。
正如蒂姆在下面的评论中提到的那样,“尽管记录环境变量要小心......它们有成为秘密的习惯,并且将它们注销往往会以明文告终不同系统负载中的文本“。如果你真的需要在注入预期配置的情况下将此类信息记录到 double-check,请尝试仅在受控开发环境中执行此操作。假设您使用本地环境的 dev
配置文件,您可以使用 @Requires
注释将特定事件侦听器限制为仅 dev
环境:
@Singleton
@Requires(env = "dev")
class OnStartupEventListener implements ApplicationEventListener<StartupEvent> {
@Value("${aws.secretkeyid}")
private String applicationYmlTestString;
@Value("${aws.keyid}")
private int keyId;
@Override
public void onApplicationEvent(StartupEvent event) {
log.warn("Application Yml Test String is: " + applicationYmlTestString);
log.warn("Key ID: " + keyId);
}
public String getApplicationYmlTestString() {
return applicationYmlTestString;
}
public void setApplicationYmlTestString(String applicationYmlTestString) {
this.applicationYmlTestString = applicationYmlTestString;
}
public int getKeyId() {
return keyId;
}
public void setKeyId(int keyId) {
this.keyId = keyId;
}
}
我正在做一个 Micronaut 项目,我想看看当应用程序在本地启动时,来自 application.yml 的环境变量是否使用 @Value 注释正确分配。 但是每次应用程序启动时,它都会显示变量没有分配给 application.yml 文件中的环境变量。
这是我的代码:
public class Application {
private static String localTestString = "I am the local String";
@Value("${aws.secretkeyid}")
public static String applicationYmlTestString;
@Value("${aws.keyid}")
private static int keyId;
public static void main(String[] args) {
Micronaut.run(Application.class);
}
static{
log.warn("Local Test String is: " + localTestString);
log.warn("Application Yml Test String is: " + applicationYmlTestString);
log.warn("Key ID: " + keyId);
}
}
这是我的application.yml
aws:
keyid: 123
secretkeyid: "abcdesdasdsddddd"
region: "europe-1"
输出:
Local Test String is: I am the local String
Application Yml Test String is: null
Key ID: 0
我们看到两个变量 applicationYmlTestString 和 keyId 没有被分配给环境变量。有没有办法解决这个问题并得到:
Application Yml Test String is: abcdesdasdsddddd
Key ID: 123
提前致谢!
您展示的示例存在两个问题。首先,Micronaut 不会向用 @Value
注释注释的静态字段 注入值。 (这并不奇怪,Spring does not support it as well。)其次,在向 non-static 字段注入值后,您将无法使用 class' 静态构造函数读取它们的值。整个应用程序上下文必须准备好读取这些值,因此您需要使用对应用程序启动事件做出反应的事件侦听器。
根据您的示例,这是实现它的最简单方法:
package micronaut.hello.world;
import io.micronaut.context.annotation.Value;
import io.micronaut.context.event.StartupEvent;
import io.micronaut.runtime.Micronaut;
import io.micronaut.runtime.event.annotation.EventListener;
import jakarta.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Singleton
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
@Value("${aws.secretkeyid}")
private String applicationYmlTestString;
@Value("${aws.keyid}")
private int keyId;
public static void main(String[] args) {
Micronaut.run(Application.class, args);
}
@EventListener
void onStartup(StartupEvent event) {
log.warn("Application Yml Test String is: " + applicationYmlTestString);
log.warn("Key ID: " + keyId);
}
public String getApplicationYmlTestString() {
return applicationYmlTestString;
}
public void setApplicationYmlTestString(String applicationYmlTestString) {
this.applicationYmlTestString = applicationYmlTestString;
}
public int getKeyId() {
return keyId;
}
public void setKeyId(int keyId) {
this.keyId = keyId;
}
}
有三点值得一提:
- 上面的例子使用了
@EventListener
注解,使给定的方法成为“event-aware”,这个方法将在应用程序(或框架)发布特定事件时被触发。 - 我们响应
io.micronaut.context.event.StartupEvent
- 启动完成后触发的事件。 - 请记住,要使此
@EventListener
注释起作用,我们需要使用@Singleton
注释应用程序 class 以使此 class 成为合适的 Micronaut bean。
或者,如果使应用程序 class 单例 bean 对您来说不合适,您可以实现 ApplicationEventListener
接口并创建一个专用 bean 来响应相同的启动事件。在这个例子中,我使用了一个静态内部class,但这只是为了让这个例子简单:
package micronaut.hello.world;
import io.micronaut.context.annotation.Value;
import io.micronaut.context.event.ApplicationEventListener;
import io.micronaut.context.event.StartupEvent;
import io.micronaut.runtime.Micronaut;
import jakarta.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
Micronaut.run(Application.class, args);
}
@Singleton
static class OnStartupEventListener implements ApplicationEventListener<StartupEvent> {
@Value("${aws.secretkeyid}")
private String applicationYmlTestString;
@Value("${aws.keyid}")
private int keyId;
@Override
public void onApplicationEvent(StartupEvent event) {
log.warn("Application Yml Test String is: " + applicationYmlTestString);
log.warn("Key ID: " + keyId);
}
public String getApplicationYmlTestString() {
return applicationYmlTestString;
}
public void setApplicationYmlTestString(String applicationYmlTestString) {
this.applicationYmlTestString = applicationYmlTestString;
}
public int getKeyId() {
return keyId;
}
public void setKeyId(int keyId) {
this.keyId = keyId;
}
}
}
但最终,您应该考虑实现配置 class 并使用它而不是使用 @Value
注释注入值。但是,无论您选择什么选项,同样的事情都适用 - 配置 class 可以注入到 non-static 字段,并且可以使用事件侦听器机制进行检查。
正如蒂姆在下面的评论中提到的那样,“尽管记录环境变量要小心......它们有成为秘密的习惯,并且将它们注销往往会以明文告终不同系统负载中的文本“。如果你真的需要在注入预期配置的情况下将此类信息记录到 double-check,请尝试仅在受控开发环境中执行此操作。假设您使用本地环境的 dev
配置文件,您可以使用 @Requires
注释将特定事件侦听器限制为仅 dev
环境:
@Singleton
@Requires(env = "dev")
class OnStartupEventListener implements ApplicationEventListener<StartupEvent> {
@Value("${aws.secretkeyid}")
private String applicationYmlTestString;
@Value("${aws.keyid}")
private int keyId;
@Override
public void onApplicationEvent(StartupEvent event) {
log.warn("Application Yml Test String is: " + applicationYmlTestString);
log.warn("Key ID: " + keyId);
}
public String getApplicationYmlTestString() {
return applicationYmlTestString;
}
public void setApplicationYmlTestString(String applicationYmlTestString) {
this.applicationYmlTestString = applicationYmlTestString;
}
public int getKeyId() {
return keyId;
}
public void setKeyId(int keyId) {
this.keyId = keyId;
}
}