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

时间:2018-12-07 12:21:33

标签: 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来验证环境属性。

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

1 个答案:

答案 0 :(得分:1)

您可以创建一些关闭处理程序组件,如下所示:

Context

然后在您的属性类上调用它;

@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);
    }
}