SpringBoot应用监控解析:Actuator实现原理( 三 )

该 自 动 配 置 的 主 要 作 用 是 针 对 HealthEndpoint 的 web 扩 展,注 解 中@ConditionalOn-WebApplication 表明只有应用类型为 Servlet 时 , 该类才会被配置 , @ConditionalOnBean 表明当存 在 HealthEndpoint 的 Bean 时才会生效 。
HealthEndpointWebExtensionConfiguration内部只初始化了HealthEndpointWebExtension对 象,创 建 该 Bean 的 条 件 为 : 容 器 中 存 在 HealthEndpoint 的 对 象 时,且HealthEndpoint-WebExtension 对象并不存在时 。
HealthEndpointWebExtension 继承自 HealthEndpointSupport,主要用来提供 health 端点和health 端点扩展的基础类 。
关于自动配置类 , 我们就讲这么多 , 读者可进一步阅读其他相关功能的源代码 。 下一 节我们将了解 HealthIndicator 的实现 。
HealthIndicator 实现
上一节我们学习了 Health 相关的自动配置 , 那么 关于 Health 的信息是如何获得的呢?这就涉及 HealthIndicator 接口的功能了 。
HealthIndicator 是一个策略模式的接口 , 继承自接口 HealthContributor.HealthContributor接口中并没有具体的方法定义 , 这是 Spring Boot 2.2.0 版本中新增的一个标记接口 , 作用于 HealthEndpoint 返回的 health 相关信息 。 相关的参与者必须为 HealthIndicator 或CompositeHealthContributor 。
在 HealthIndicator 接口中定义了一个具有默认实现的 getHealth 方法和抽象的 health 方法 , 其中 getHealth 方法也是 Spring Boot 2.2.0 版本新增的 。
HealthIndicator 接口源代码如下 。
@FunctionalInterfacepublic interface HealthIndicator extends HealthContributor {//根据 includeDetails,返回 health 指示default Health getHealth(boolean includeDetails) {Health health = health();//如果 includeDetails 为 true 则直接返@health,否则返 回不携带洋情的 healthreturn includeDetails ? health : health . withoutDetails();//返回 health 指示Health health();}其中 , health 方法返回 Health 对象 , 存储着应用程序的健康信息 。
getHealth 方法会根据 includeDetails 参数判断是直接返回 health 方法的结果 , 还是返回经过处理不携带详情的 Health 对象 。
常见的 HealthIndicator 实现 , 比如 JDBC 数据源( DataSourceHealthIndicator )磁盘健康指示器(DiskSpaceHealthIndicator)、Redis 健康 (RedisHealthIndicator) 等 。
HealthIndicator 接 口 的 实 例 是 如 何 创 建 的 呢 ? 我 们 以 JDBC 数 据 源 的DataSourceHealth-Indicator 为 例。首 先 DataSourceHealthIndicator 继 承AbstractHealthIndicator, AbstractHealthIndicator 又 实现了 HealthIndicator 接口 , 也就是说 DataSourceHealthIndicator 是 HealthIndicator 类型 。
DataSourceHealthIndicator的实例化是通过DataSourceHealthContributorAutoConfiguration 来完成的 , 相关源代码如下 。
@Configuration(proxyBeanMethods = false)@ConditionalOnClass({ JdbcTemplate. class, AbstractRoutingDataSource.class})@ConditionalOnBean(DataSource. class)@ConditionalOnEnabledHealthIndicator("db")@AutoConfigureAfter (DataSourceAutoConfiguration. class)public class DataSourceHealthContributorAutoConfiguration extendsCompositeHealthContributorConfigurationimplements InitializingBean {//实例化 Heal thContributor@Bean@Condit ionalOnMissingBean(name = { "dbHealthIndicator", "dbHea lthContributor" })public HealthContributor dbHealthContributor(Map dataSources) {//主要通过 DataSource 数据源通过反射生成 Heal thContributor,//这里通过父类 CompositeHeal thContributorConfigurat ion 的 createContributor方法进行调用// 当前类重写的 create Indicator 方法return createContributor(dataSources);//实例化对应的 AbstractHealthIndicator, 重 写父类 createIndicator 方法@Overrideprotected AbstractHealthIndicator createIndicator(DataSource source) {if (source instanceof AbstractRout ingDataSource) {return new RoutingDataSourceHealthIndicator();}//实例化 DataSourceHealthIndicator, 参数数据源和查询语句return new DataSourceHealthIndicator(source, getValidationQuery(source));//获取检测所需的查询语句private String getValidationQuery (DataSource source) {//获取 DataSourcePooLMetadata 对象 ,并 调用其 getVal idationQuery 方法// getVal idationQuery 方法用来获得执行验证数据库链接是否正常的 SQLDataSourcePoolMetadata poolMetadata = http://kandian.youth.cn/index/this . poolMetadataProvider . getDa-taSourcePoolMetadata(source);return (poolMetadata != null) ? poolMetadata. getValidationQuery() : null;} 。。。 }关于 DataSourceHealthContributorAutoConfiguration 自动配置生效的条件就不详细解释了 , 在其内部可以看到 , 通过 createlndicator 方法实现了 DataSourceHealthIndicator 的实例化操作 。 该方法并没有直接被调用 , 而是通过 dbHealthContributor 方法调用父类的方法实现间接调用的 。
DataSourceHealthIndicator 的构造方法有两个参数:一个数据源对象 , 一个 query 语句 。在该类中实现数据源健康检查的基本原理就是通过数据源连接数据库并执行相应的查询语句来验证连接是否正常 。