当数据库关闭时我调用heathIndicator.health()
方法时,它将抛出NullPointerException
。堆栈跟踪显示AbstractHealthIndicator中的logger
对象为null。我还通过调试对其进行了验证。数据库启动后,代码可以正常工作,因为未调用记录器。我不太明白为什么会发生这种情况。
这是Spring的AbstractHealthIndicator中health
方法的代码
@Override
public final Health health() {
Health.Builder builder = new Health.Builder();
try {
doHealthCheck(builder);
}
catch (Exception ex) {
// null pointer exception happens here, logger is null.
if (this.logger.isWarnEnabled()) {
String message = this.healthCheckFailedMessage.apply(ex);
this.logger.warn(StringUtils.hasText(message) ? message : DEFAULT_MESSAGE,
ex);
}
builder.down(ex);
}
return builder.build();
}
最佳答案
我在AbstractHealthIndicator
类上遇到了同样的问题。就我而言,问题在于我的健康指标中使用了@Transactional
。由于有了这个注释,Spring为我的课程创建了一个CGLIB代理。这不应该是一个问题,但是我想是因为AbstractHealthIndicator.health()
中的AbstractHealthIndicator
方法是最终的,CGLIB代理无法正常工作。显而易见的解决方案不是使用@Transactional
,而是将支票委托给服务。
这也是在初始化期间指定的。记录如下:
o.s.aop.framework.CglibAopProxy: Unable to proxy interface-implementing method [public final org.springframework.boot.actuate.health.Health org.springframework.boot.actuate.health.AbstractHealthIndicator.health()] because it is marked as final: Consider using interface-based JDK proxies instead!