gpt4 book ai didi

java - 如何根据属性有条件地使 Spring Boot 应用程序在启动时终止

转载 作者:行者123 更新时间:2023-11-30 06:01:59 25 4
gpt4 key购买 nike

我想实现以下用例 - 只有在 application.yaml 中设置了某个属性时,我的 Spring Boot 应用程序才会启动:

myapp:
active: true

如果未设置该属性,则上下文初始化应该失败并显示一条消息,指出该属性丢失。

我在本主题中找到了如何实现它:Spring Boot - Detect and terminate if property not set?但是我不能遵循这种方法的问题是,在加载检查此属性的 bean 之前,上下文初始化可能会失败。

例如,如果其他一些 bean 由于缺少另一个属性而无法加载,则上下文初始化将在此时失败,并且我的 bean(检查所需属性)将不会被加载。这对我来说不合适,因为我希望在加载任何其他 bean 之前首先检查 myapp.active 属性。

我想要这样的原因是在运行应用程序时应该设置特定的配置文件 - application-[profile].yaml 包含 myapp.active: true 和加载上下文所需的其他一些强制属性。

我希望我的应用程序总是因为 myapp.active 不正确而失败,这样我就可以输出一条有意义的消息,告知配置文件丢失并且应用程序必须使用其中一个配置文件(来自给定的配置文件列表)运行).一些不是开发人员的人正在运行该应用程序,所以我希望他们知道为什么该应用程序没有运行,否则他们会认为该应用程序中存在一些错误。

我怎样才能做到这一点?是否有可能在加载 bean 之前以某种方式读取该属性?我想避免在所有 bean 上设置 @DependsOn(或通过 BeanPostProcesser 做同样的事情)并寻求更优雅的解决方案。

最佳答案

如果您使用属性条件,应用程序将不会启动。够快吗?

 @SpringBootApplication
@ConditionalOnProperty(name = "myapp.active")
public class FastFailWhenPropertyNotPresentApplication {

public static void main(String[] args) {
SpringApplication.run(FastFailWhenPropertyNotPresentApplication.class, args);
}

}

基本上 @SpringBootApplication 只是一个 @Configuration 类。

您有一个选项 matchIfMissing,您可以使用它来指定如果未设置该属性,条件是否应该匹配。默认为假。

编辑:

更好的解决方案是通过 @ConfigurationProperties 结合 @Validated 来配置您的属性,这样您就可以使用 javax.validation.constraints 注释。

package stackoverflow.demo;

import javax.validation.constraints.AssertTrue;
import javax.validation.constraints.NotNull;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

@Component
@ConfigurationProperties(prefix = "myapp")
@Validated
public class MyAppProperties {

@AssertTrue
@NotNull
private Boolean active;

public Boolean getActive() {
return active;
}

public void setActive(Boolean active) {
this.active = active;
}

}

注意:您可以省略 @ConditionalOnProperty(name = "myapp.active")

@AssertTrue@NotNull 结合使用,因为 @AssertTrue 将 null 元素视为有效。

并且 spring-boot 会免费生成一条不错的错误消息:

***************************
APPLICATION FAILED TO START
***************************

Description:

Binding to target org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'myapp' to stackoverflow.demo.MyAppProperties failed:

Property: myapp.active
Value: false
Origin: class path resource [application.properties]:1:16
Reason: must be true


Action:

Update your application's configuration

编辑(更新问题后)


更快的方法:您的应用程序不会启动,也不会加载应用程序上下文

package stackoverflow.demo;

import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.io.ClassPathResource;

@SpringBootApplication
public class FastFailWhenPropertyNotPresentApplication {

static Boolean active;

static {

YamlPropertiesFactoryBean yaml = new YamlPropertiesFactoryBean();
yaml.setResources(new ClassPathResource("application.yaml"));

active = (Boolean) yaml.getObject().getOrDefault("myapp.active", false);

}


public static void main(String[] args) {
if (!active) {
System.err.println("your fail message");
} else {
SpringApplication.run(FastFailWhenPropertyNotPresentApplication.class, args);
}
}

}

编辑

另一个可能最适合您需求的解决方案...

通过监听ApplicationEnvironmentPreparedEvent

Event published when a {@link SpringApplication} is starting up and the * {@link Environment} is first available for inspection and modification. *

注意:您不能使用@EventListener,但您已将监听器添加到SpringApplication

package stackoverflow.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.context.ApplicationListener;

@SpringBootApplication
public class FastFailWhenPropertyNotPresentApplication {


static class EnvironmentPrepared implements ApplicationListener<ApplicationEnvironmentPreparedEvent>{
@Override
public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
Boolean active = event.getEnvironment().getProperty("myapp.active",Boolean.class,Boolean.FALSE);
if(!active) {
throw new RuntimeException("APPLICATION FAILED TO START: ACTIVE SHOULD BE TRUE ");
}
}
};


public static void main(String[] args) throws Exception {
SpringApplication springApplication = new SpringApplication(FastFailWhenPropertyNotPresentApplication.class);
springApplication.addListeners(new FastFailWhenPropertyNotPresentApplication.EnvironmentPrepared());
springApplication.run(args);
}

}

关于java - 如何根据属性有条件地使 Spring Boot 应用程序在启动时终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56152340/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com