Два основных недостатка вашего решения IMHO - это то, что вам нужен новый класс для каждой новой проверки работоспособности и использование полевой инъекции . Другим способом реализации этого было бы следующее.
Я создал простой класс для «бизнес-логики c». Этот класс реализует HealthIndicator и не является управляемым компонентом Spring. Он получает все необходимые зависимости от конструктора, чтобы избежать внедрения поля.
public class CustomHealthCheck implements HealthIndicator {
private final String url; // use URL or URI instead of String?
public CustomHealthCheck(String url) {
this.url = url;
}
@Override
public Health health() {
// call url
return Health.up().build();
}
}
Чтобы заставить их работать с Spring, я создал класс конфигурации, который создает бины Spring. Таким образом, нет необходимости создавать новый класс для каждой новой проверки работоспособности, имеющий те же логики c, что и существующий, только новый метод внутри этого класса.
@Configuration
public class CustomHealthChecks {
@Bean
public CustomHealthCheck firstHealthCheck(@Value("${url1}") String url) {
return new CustomHealthCheck(url);
}
@Bean
public CustomHealthCheck secondHealthCheck(@Value("${url2}") String url) {
return new CustomHealthCheck(url);
}
}
И простой тест для убедитесь, что у меня есть два объекта HealthIndicator в моем весеннем контексте.
@Test
public void produces_expected_health_indicators() {
ApplicationContextRunner runner = new ApplicationContextRunner();
runner.withPropertyValues("url1=https://stackoverflow.com/", "url2=https://start.spring.io/")
.withUserConfiguration(CustomHealthChecks.class)
.run(context -> {
assertThat(context).getBeans(HealthIndicator.class).hasSize(2);
});
}