java - 如何在配置过程中关闭Spring应用程序?

标签 java spring spring-boot

在配置过程中或应用程序上下文初始化后关闭 Spring 应用程序的最佳实践是什么?

例如,就我而言,我有多个@ConfigurationProperties,并且必须至少指定其中之一,否则应用程序将关闭。我应该使用 @Conditional、一些常规的 @ConfigurationProperties 进行验证还是其他东西?

<小时/>

我决定将验证与常规@ConfigurationProperties一起使用

@Constraint(validatedBy = AtLeastOneOfTheFieldsValidator.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AtLeastOneOfTheFields {

    String message() default "At least one of the fields must be specified";

    String onBooleanCondition();

    String[] fields();

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    @interface List {

        AtLeastOneOfTheFields[] value();
    }
}
<小时/>
public class AtLeastOneOfTheFieldsValidator implements ConstraintValidator<AtLeastOneOfTheFields, Object> {

    private String[] fields;

    private String booleanConditionField;

    @Override
    public void initialize(AtLeastOneOfTheFields atLeastOneOfTheFields) {
        this.fields = atLeastOneOfTheFields.fields();
        this.booleanConditionField = atLeastOneOfTheFields.onBooleanCondition();
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
        Object booleanConditionValue = new BeanWrapperImpl(value).getPropertyValue(booleanConditionField);

        if (Objects.isNull(booleanConditionValue) || Objects.equals(Boolean.TRUE, booleanConditionValue)) {
                return Arrays.stream(fields)
                    .map(field -> new BeanWrapperImpl(value).getPropertyValue(field))
                    .anyMatch(Objects::nonNull);
        }
        return true;
    }
}
<小时/>
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "bot")
@Validated
@AtLeastOneOfTheFields(fields = {"facebook.page-access-token", "telegram.token", "viber.token"},
        onBooleanCondition = "enabled",
        message = "At leas one of bot token must be specified if property bot.enabled = 'true'.")
public class BotConfig {

    @NotNull
    private Boolean enabled;

    @NestedConfigurationProperty
    private FacebookBotConfig facebook;

    @NestedConfigurationProperty
    private TelegramBotConfig telegram;

    @NestedConfigurationProperty
    private ViberBotConfig viber;
}
<小时/>

另一种变体是使用 ApplicationContextInitializer 来验证环境属性。

我很高兴收到您的意见或建议。 =)

最佳答案

您可以像这样创建一些关闭处理程序组件:

@Component
public class ShutdownHandler {

    @Autowired
    private ApplicationContext applicationContext;

    public void shutdown(int code) {     // to shutdown you have to put 0 number
        SpringApplication.exit(applicationContext, () -> code);
    }
}

并在您的属性类上调用它;

@ConfigurationProperties
public class ConfigProperties {

    @Autowired
    private ShutdownHandler handler;

    public void someMethod() {            
        if (isValid){
           handler.shutdown(0);
        }
    }

}

关于java - 如何在配置过程中关闭Spring应用程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53669454/

相关文章:

java - 如何在 Hibernate 中使用 @Qualifier

java - Android 应用程序因单击按钮而崩溃

java - 不带修剪的自由标记列表

java - 没有 Spring Security 记住我以编程方式登录时创建的 cookie

java - 如何从类路径中通过多个注释查找类?

java - Spring Restdocs 响应负载包含可选的空对象列表

java - 以不区分大小写的顺序输出文本

java - Spring Boot 中的 JSON Java 8 LocalDateTime 格式

java - JToolbar 中 JButton 中的 AbstractAction 没有文本

spring - 可以在 Spring 上下文中使用gradle替换值吗?