我正在尝试使用弹簧执行器进行健康检查。我需要执行健康检查的网址很少,但是调用它们的方式却非常相似。我试图创建一个基类,该基类实现healthindicator和从基类扩展的子类,这些基类传递实际的url,然后调用health方法。有更好的方法吗?
基本健康检查类别
@Component
public class BaseHealthCheck implements HealthIndicator{
private String url;
@Override
public Health health() {
// call url
return Health.up().build();
}
private void setUrl(String url){
this.url = url
}
}
1级儿童
@Component
public class Child1HealthCheck extends BaseHealthCheck {
@Value("${childurl1}")
private String url;
@Override
public Health health() {
super.health();
}
@PostConstruct
private void setUrl(){
super.setUrl(url);
}
}
2级儿童
@Component
public class Child2HealthCheck extends BaseHealthCheck {
@Value("${childurl2}")
private String url;
@Override
public Health health() {
super.health();
}
@PostConstruct
private void setUrl(){
super.setUrl(url);
}
}
答案 0 :(得分:1)
解决方案恕我直言的两个主要缺点是,每次进行新的健康检查和使用field injection时都需要一个新的类。实现此目标的另一种方法是:
我为“业务逻辑”创建了一个简单的类。此类实现HealthIndicator,并且不是Spring托管的bean。它从构造函数获取所有必需的依赖项,以避免字段注入。
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 Bean。因此,无需为每个具有与现有逻辑相同的逻辑的新健康检查创建一个新类,而只需在此类中创建一个新方法即可。
@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);
}
}
还有一个简单的测试,以验证我的spring上下文中有两个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);
});
}