我想实现下面的用例——我的Spring Boot应用程序应该只在应用程序中有某个属性时启动。yaml设置为:
myapp
active: true
如果未设置该属性,则上下文初始化将失败,并显示一条消息,表明该属性丢失。
我在这个主题中找到了如何实现它:Spring启动-检测和终止,如果属性没有设置?但是我不能遵循这种方法的问题是,在加载检查此属性的bean之前,上下文初始化可能会失败。
例如,如果其他bean由于缺少另一个属性而无法加载,那么上下文初始化将在该点失败,并且检查所需属性的Mybean将不会加载。这对我来说不合适,因为我想要myapp。在加载任何其他bean之前,首先检查活动属性。
我之所以想这样做,是因为在运行应用程序时应该设置特定的配置文件-应用程序-[profile]。yaml包含“myapp.active:true”和加载上下文所需的一些其他必需属性。
我希望我的应用程序总是因为myapp而失败。active not true,以便我可以输出一条有意义的消息,告知配置文件丢失,并且应用程序必须使用其中一个配置文件(来自给定的配置文件列表)运行。一些不是开发者的家伙正在运行这个应用程序,所以我想让他们知道为什么这个应用程序没有运行,否则他们会认为这个应用程序中有一些bug。
我怎样才能做到这一点?是否有可能在加载bean之前读取属性?我希望避免在所有bean上设置@DependsOn(或者通过BeanPostProcessor进行相同的设置),我正在寻找一个更优雅的解决方案。
如果使用属性条件,应用程序将无法启动。够快吗?
@SpringBootApplication
@ConditionalOnProperty(name = "myapp.active")
public class FastFailWhenPropertyNotPresentApplication {
public static void main(String[] args) {
SpringApplication.run(FastFailWhenPropertyNotPresentApplication.class, args);
}
}
基本上,@springbootplication
只是一个@配置
类。
您有一个选项matchIfMissing
,可用于指定如果未设置属性,条件是否应匹配。默认为false。
编辑:
更好的解决方案是通过@ConfigurationProperties
和@Validated
组合来配置属性,这样您就可以使用javax了。验证。约束和注释。
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;
}
}
注意:您可以省略@条件属性(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
当{@link SpringApplication}启动且*{@link Environment}首次可用于检查和修改时发布的事件*
注意:您不能使用@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);
}
}
我有一个Spring Boot应用程序,它有一些外部依赖(例如,项目之外的文件,需要存在,以便应用程序正确启动)。 和一系列其他例外。有没有一种方法可以恰当地做到这一点?
问题内容: 我尝试使用范围类型APPLICATION和带有@ Create,@ Beg的方法来注释类,但这似乎不起作用。 我想要的是在应用程序启动时立即启动无限循环。 问题答案: 如果希望在初始化后立即执行方法,则可以使用以下注释:
我有一份Java申请。 应用程序有一个决定应用程序是否在启动时启动的设置。 目前,我通过在StartUp items文件夹中放置/删除快捷方式实现了这一点。 然而,我想知道是否有更好的方法来处理这种行为。 编辑 是的,是视窗。抱歉之前没有清除。 应用程序有一个UI,用户可以在其中触发操作,并且应用程序在运行时定期在后台运行一些任务。 @Peter,如何使用应用程序中的代码更改注册表?这种方法是否与
我想对Spring数据使用ElasticSearch。我使用的是Spring 5、Spring Boot 2和ElasticSearch 7.4。Docker compose: 马文: 存储库: 配置: 和错误时启动应用程序: 引起:java.lang.NoSuchMEDError:org.springframework.http.HttpHeaders.(Lorg/springframe/uti
问题内容: 我有一个Java应用程序。 该应用程序具有一个设置,该设置决定该应用程序是否在启动时启动。 目前,我可以通过在“启动项目”文件夹中放置/删除快捷方式来实现此目的。 但是,我想知道是否有更好的方法来处理此行为。 编辑 是的,它是Windows。抱歉,之前没有清除该内容。 该应用程序具有一个用户可以在其中触发动作的UI,并且该应用程序在运行时会定期在后台运行一些任务。 @Peter,如何在
我正在尝试使用简单的spring启动应用程序。我在ApplicationContext上启动应用程序时遇到问题。 2017-04-26 11:17:31.101警告14528---[main]s.c.a.AnnotationConfigApplicationContext:上下文初始化期间遇到异常-取消刷新尝试:org。springframework。豆。工厂未满足的PendencyExcepti