Springboot应用执行器Actuator源码分析

文章目录

  • 一、认识Actuator
    • 1、回顾Actuator
    • 2、Actuator重要端点
  • 二、源码分析
    • 1、Endpoint自动装配
      • (1)自动配置入口
      • (2)普通Endpoint自动装配
      • (3)配置Web - Endpoint
      • (4)注册Endpoint为Mvc映射
    • 2、BeansEndpoint自动装配原理
      • (1)自动装配类
      • (2)BeansEndpoint
      • (3)执行结果
    • 3、MappingsEndpoint自动装配原理
      • (1)自动装配类
      • (2)MappingsEndpoint
      • (3)执行结果
    • 4、ShutdownEndpoint自动装配原理
      • (1)自动装配类
      • (2)ShutdownEndpoint

一、认识Actuator

1、回顾Actuator

Actuator是Springboot提供运行时数据交互的规范。
它覆盖应用内心戏、环境配置、度量指标、敏感操作。
交互方式为Http Web或者JMX。

Spring Boot Actuator ——健康检查神器

2、Actuator重要端点

在这里插入图片描述

二、源码分析

1、Endpoint自动装配

(1)自动配置入口

在这里插入图片描述

(2)普通Endpoint自动装配

@AutoConfiguration
@ConditionalOnAvailableEndpoint(endpoint = EnvironmentEndpoint.class) // EnvironmentEndpoint可用
@EnableConfigurationProperties(EnvironmentEndpointProperties.class)// 构建属性配置文件
public class EnvironmentEndpointAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean
	public EnvironmentEndpoint environmentEndpoint(Environment environment, EnvironmentEndpointProperties properties,
			ObjectProvider<SanitizingFunction> sanitizingFunctions) {
		EnvironmentEndpoint endpoint = new EnvironmentEndpoint(environment,
				sanitizingFunctions.orderedStream().collect(Collectors.toList()));
		String[] keysToSanitize = properties.getKeysToSanitize();
		if (keysToSanitize != null) {
			endpoint.setKeysToSanitize(keysToSanitize);
		}
		String[] additionalKeysToSanitize = properties.getAdditionalKeysToSanitize();
		if (additionalKeysToSanitize != null) {
			endpoint.keysToSanitize(additionalKeysToSanitize);
		}
		return endpoint;
	}

	@Bean
	@ConditionalOnMissingBean
	@ConditionalOnBean(EnvironmentEndpoint.class)
	@ConditionalOnAvailableEndpoint(exposure = { EndpointExposure.WEB, EndpointExposure.CLOUD_FOUNDRY })
	public EnvironmentEndpointWebExtension environmentEndpointWebExtension(EnvironmentEndpoint environmentEndpoint) {
		return new EnvironmentEndpointWebExtension(environmentEndpoint);
	}

}

(3)配置Web - Endpoint

通过自动配置类WebEndpointAutoConfiguration进行自动装配。


// org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointAutoConfiguration#webEndpointDiscoverer
@Bean
@ConditionalOnMissingBean(WebEndpointsSupplier.class)
public WebEndpointDiscoverer webEndpointDiscoverer(ParameterValueMapper parameterValueMapper,
		EndpointMediaTypes endpointMediaTypes, ObjectProvider<PathMapper> endpointPathMappers,
		ObjectProvider<OperationInvokerAdvisor> invokerAdvisors,
		ObjectProvider<EndpointFilter<ExposableWebEndpoint>> filters) {
		// 把所有的Web - Endpoint都搜集到
	return new WebEndpointDiscoverer(this.applicationContext, parameterValueMapper, endpointMediaTypes,
			endpointPathMappers.orderedStream().collect(Collectors.toList()),
			invokerAdvisors.orderedStream().collect(Collectors.toList()),
			filters.orderedStream().collect(Collectors.toList()));
}

(4)注册Endpoint为Mvc映射

通过自动配置类WebMvcEndpointManagementContextConfiguration注册Endpoint为Mvc映射。

通过各种方式定义的Endpoint,创建为WebMvcEndpointHandlerMapping,进行Web映射。

// org.springframework.boot.actuate.autoconfigure.endpoint.web.servlet.WebMvcEndpointManagementContextConfiguration#webEndpointServletHandlerMapping
@Bean
@ConditionalOnMissingBean
public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier,
		ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier,
		EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties,
		WebEndpointProperties webEndpointProperties, Environment environment) {
	List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();
	Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
	allEndpoints.addAll(webEndpoints);
	allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
	allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
	String basePath = webEndpointProperties.getBasePath();
	EndpointMapping endpointMapping = new EndpointMapping(basePath);
	boolean shouldRegisterLinksMapping = shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
	return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes,
			corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath),
			shouldRegisterLinksMapping, WebMvcAutoConfiguration.pathPatternParser);
}

2、BeansEndpoint自动装配原理

(1)自动装配类

@AutoConfiguration
@ConditionalOnAvailableEndpoint(endpoint = BeansEndpoint.class)
public class BeansEndpointAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean
	public BeansEndpoint beansEndpoint(ConfigurableApplicationContext applicationContext) {
		// 创建一个BeansEndpoint
		return new BeansEndpoint(applicationContext);
	}

}

(2)BeansEndpoint

// id就是可以访问的web路径
@Endpoint(id = "beans")
public class BeansEndpoint {
// 读操作
@ReadOperation
public ApplicationBeans beans() {
	Map<String, ContextBeans> contexts = new HashMap<>();
	// 将所有容器都拿出来
	ConfigurableApplicationContext context = this.context;
	while (context != null) {
		// 将Bean都拿出来,封装成一个ContextBeans
		contexts.put(context.getId(), ContextBeans.describing(context));
		context = getConfigurableParent(context);
	}
	// 创建一个ApplicationBeans
	// 返回的信息就会json格式化到响应
	return new ApplicationBeans(contexts);
}
// 返回的对象
public static final class ApplicationBeans {

	private final Map<String, ContextBeans> contexts;

	private ApplicationBeans(Map<String, ContextBeans> contexts) {
		this.contexts = contexts;
	}

	public Map<String, ContextBeans> getContexts() {
		return this.contexts;
	}

}

(3)执行结果

在这里插入图片描述

3、MappingsEndpoint自动装配原理

(1)自动装配类

@AutoConfiguration
@ConditionalOnAvailableEndpoint(endpoint = MappingsEndpoint.class)
public class MappingsEndpointAutoConfiguration {

	// 配置Mapping
	@Bean
	public MappingsEndpoint mappingsEndpoint(ApplicationContext applicationContext,
			ObjectProvider<MappingDescriptionProvider> descriptionProviders) {
		return new MappingsEndpoint(descriptionProviders.orderedStream().collect(Collectors.toList()),
				applicationContext);
	}

	// 后面还有关于Servlet的相关配置,此处就先不看

(2)MappingsEndpoint

// web访问路径
@Endpoint(id = "mappings")
public class MappingsEndpoint {
// org.springframework.boot.actuate.web.mappings.MappingsEndpoint#mappings
@ReadOperation
public ApplicationMappings mappings() {
	ApplicationContext target = this.context;
	Map<String, ContextMappings> contextMappings = new HashMap<>();
	while (target != null) {
		// 查找所有的Mapping
		contextMappings.put(target.getId(), mappingsForContext(target));
		target = target.getParent();
	}
	return new ApplicationMappings(contextMappings);// 返回的信息就会json格式化到响应
}

// org.springframework.boot.actuate.web.mappings.MappingsEndpoint#mappingsForContext
private ContextMappings mappingsForContext(ApplicationContext applicationContext) {
	Map<String, Object> mappings = new HashMap<>();
	this.descriptionProviders.forEach(
			(provider) -> mappings.put(provider.getMappingName(), provider.describeMappings(applicationContext)));
	return new ContextMappings(mappings,
			(applicationContext.getParent() != null) ? applicationContext.getId() : null);
}

在这里插入图片描述

(3)执行结果

在这里插入图片描述
在这里插入图片描述

4、ShutdownEndpoint自动装配原理

(1)自动装配类

@AutoConfiguration
@ConditionalOnAvailableEndpoint(endpoint = ShutdownEndpoint.class)
public class ShutdownEndpointAutoConfiguration {

	@Bean(destroyMethod = "")
	@ConditionalOnMissingBean
	public ShutdownEndpoint shutdownEndpoint() {
		return new ShutdownEndpoint();
	}

}

(2)ShutdownEndpoint

// 默认是不开启的,因为安全性要求极高
@Endpoint(id = "shutdown", enableByDefault = false)
public class ShutdownEndpoint implements ApplicationContextAware {

	private static final Map<String, String> NO_CONTEXT_MESSAGE = Collections
		.unmodifiableMap(Collections.singletonMap("message", "No context to shutdown."));

	private static final Map<String, String> SHUTDOWN_MESSAGE = Collections
		.unmodifiableMap(Collections.singletonMap("message", "Shutting down, bye..."));

	private ConfigurableApplicationContext context;

	// 写操作
	@WriteOperation
	public Map<String, String> shutdown() {
		if (this.context == null) {
			return NO_CONTEXT_MESSAGE; // 返回的信息就会json格式化到响应
		}
		try {
			return SHUTDOWN_MESSAGE;
		}
		finally {
			// 另起一个线程进行shutdown操作,目的是优雅关机。
			Thread thread = new Thread(this::performShutdown);
			thread.setContextClassLoader(getClass().getClassLoader());
			thread.start();
		}
	}

	private void performShutdown() {
		try {
			// 暂停500毫秒
			Thread.sleep(500L);
		}
		catch (InterruptedException ex) {
			Thread.currentThread().interrupt();
		}
		// 执行Spring容器关闭操作
		this.context.close();
	}

	@Override
	public void setApplicationContext(ApplicationContext context) throws BeansException {
		if (context instanceof ConfigurableApplicationContext) {
			this.context = (ConfigurableApplicationContext) context;
		}
	}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/412296.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序-全局配置

个人笔记&#xff0c;仅供参考。 1.entryPagePath 代码&#xff1a; "entryPagePath": "pages/index/index" 具体用法&#xff1a; 2.pages 小程序中新增/减少页面&#xff0c;都需要对 pages 数组进行修改。 代码&#xff1a; "pages": [&…

设计模式系列文章-7个创建型模式更新已完结

其实从2019年开始就有些一套关于设计模式的系列文章&#xff0c;但是因为种种原因一直搁置到现在。直到2024年才又恢复更新。 24年1月份上旬一直在弄博客站&#xff1a;https://jaune162.blog 的搭建 24年1月份下旬弄专题站&#xff1a;https://books.jaune162.blog 的搭建。…

设计模式(十) - 工厂方式模式

前言 在此前的设计模式&#xff08;四&#xff09;简单工厂模式中我们介绍了简单工厂模式&#xff0c;在这篇文章中我们来介绍下工厂方法模式&#xff0c;它同样是创建型设计模式&#xff0c;而且又有些类似&#xff0c;文章的末尾会介绍他们之间的不同。 1.工厂方法模式简介 …

每日五道java面试题之spring篇(七)

目录&#xff1a; 第一题. 什么是Spring beans&#xff1f;第二题. 一个 Spring Bean 定义 包含什么&#xff1f;第三题. 如何给Spring 容器提供配置元数据&#xff1f;Spring有几种配置方式?第四题. Spring基于xml注入bean的几种方式?第五题&#xff1a;你怎样定义类的作用域…

性能优化问题思考总结

INP 是什么&#xff1f; Interaction to Next Paint (INP) INP是一项指标&#xff0c;通过观察用户在访问网页期间发生的所有点击、点按和键盘互动的延迟时间&#xff0c;评估网页对用户互动的总体响应情况。 互动是指在同一逻辑用户手势期间触发的一组事件处理脚本。例如&a…

酷开科技,让酷开系统成为现代生活的变革者

电视&#xff0c;从问世就一直受到人们的追捧。还记得小时候一家人围坐在电视机前的场景&#xff0c;小小的黑白屏幕&#xff0c;牢牢的吸引着大家的目光。随着科技的不断进步&#xff0c;我们的生活也发生了翻天覆地的变化。而电视&#xff0c;也从笨重的黑白电视变成了轻薄的…

jenkins + gitlab + nginx 自动部署(webhook)

一、意义 当代码仓库被更新时&#xff0c;Jenkins会自动拉取代码进行构建。 适用于测试环境 二、jenkins gitlab nginx 自动部署(webhook) 1.准备服务器 ①安装Jenkins&#xff08;Java17&#xff0c;tomcat9&#xff09; ②安装gitlab &#xff08;16&#xff09; ③…

深入理解Python中的JSON模块:基础大总结与实战代码解析【第102篇—JSON模块】

深入理解Python中的JSON模块&#xff1a;基础大总结与实战代码解析 在Python中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;模块是处理JSON数据的重要工具之一。JSON是一种轻量级的数据交换格式&#xff0c;广泛应用于Web开发、API通信等领域。本文将…

2023 re:Invent 用 Amazon Q 打造你的知识库

前言 随着 ChatGPT 的问世&#xff0c;我们迎来了许多创新和变革的机会。一年一度的亚马逊云科技大会 re:Invent 也带来了许多前言的技术&#xff0c;其中 Amazon CEO Adam Selipsky 在 2023 re:Invent 大会中介绍 Amazon Q 让我印象深刻&#xff0c;这预示着生成式 AI 的又一…

【wu-acw-client 使用】案例

wu-acw-client 使用 项目介绍&#xff0c;使用acw-client&#xff0c;创建对应Java项目的增删改查&#xff08;ORM&#xff1a;Lazy ORM、mybatis&#xff09;&#xff0c;项目模块架构&#xff1a;mvc、feign、ddd 演示项目环境&#xff1a;idea 、mac、mysql、jdk17 spring …

geotools解析shp 提示 opengis.*.SimpleFeatureType‘ 不在其界限内

问题:&#xff08; geotools.version&#xff1a;31-SNAPSHOT&#xff09; 解析shp文件时提示类型SimpleFeatureType不在其界限内 解决&#xff1a; 在引用处将org.opengis.feature.simple.SimpleFeatureType 改为 org.geotools.api.feature.simple.SimpleFeatureType

qt-C++笔记之使用QProcess去执行一个可执行文件时指定动态库所存放的文件夹lib的路径

qt-C笔记之使用QProcess去执行一个可执行文件时指定动态库所存放的文件夹lib的路径 参考博文&#xff1a; 1.C笔记之执行一个可执行文件时指定动态库所存放的文件夹lib的路径 2.Linux笔记之LD_LIBRARY_PATH详解 3.qt-C笔记之使用QProcess去执行一个可执行文件时指定动态库所存放…

LeetCode 0938.二叉搜索树的范围和:深度优先搜索(可中序遍历)

【LetMeFly】938.二叉搜索树的范围和&#xff1a;深度优先搜索&#xff08;可中序遍历&#xff09; 力扣题目链接&#xff1a;https://leetcode.cn/problems/range-sum-of-bst/ 给定二叉搜索树的根结点 root&#xff0c;返回值位于范围 [low, high] 之间的所有结点的值的和。…

数一满分150分总分451东南大学920电子信息通信考研Jenny老师辅导班同学,真题大纲,参考书。

记录用来打破的&#xff0c;信息通信考研Jenny老师2024级辅导班同学&#xff0c;数一满分150分&#xff0c;专业课920专业基础综合143&#xff0c;总分451分&#xff0c;一位及其优秀的本科985报考东南大学信息学院的学生&#xff0c;东南大学920考研&#xff0c;东南大学信息科…

查看NGINX版本

查看Nginx版本有几种常用方法&#xff1a; 命令行&#xff1a; 在Linux或macOS系统中打开终端&#xff0c;然后输入以下命令之一&#xff1a; nginx -v 或者 nginx -V -v 参数将输出简短的nginx版本信息。 -V 参数&#xff08;大写&#xff09;将输出更详细的版本和配置信息&am…

Zoho ToDo 满足您的需求:任务管理满足隐私和安全要求

任务管理工具已经成为我们日常生活中不可或缺的一部分&#xff0c;它们帮助我们处理各种事务&#xff0c;从杂项和愿望清单到管理截止日期和资源。这些工具不仅仅是简单的任务列表&#xff0c;它们掌握了项目的蓝图、雄心勃勃的目标和完成的最后期限。然而随着这些工具的使用越…

【web APIs】1、(学习笔记)有案例!

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、概念二、使用步骤1.获取DOM对象2.操作元素内容3.属性修改3.1.常用属性修改3.2.控制样式属性3.3.操作类名(className) 操作CSS3.4.操作表单元素属性3.5.自定…

YOLOv9-Openvino和ONNXRuntime推理【CPU】

1 环境&#xff1a; CPU&#xff1a;i5-12500 Python&#xff1a;3.8.18 2 安装Openvino和ONNXRuntime 2.1 Openvino简介 Openvino是由Intel开发的专门用于优化和部署人工智能推理的半开源的工具包&#xff0c;主要用于对深度推理做优化。 Openvino内部集成了Opencv、Tens…

小龙虾优化算法COA求解不闭合SD-MTSP,可以修改旅行商个数及起点(提供MATLAB代码)

一、小龙虾优化算法COA 小龙虾优化算法&#xff08;Crayfsh optimization algorithm&#xff0c;COA&#xff09;由Jia Heming 等人于2023年提出&#xff0c;该算法模拟小龙虾的避暑、竞争和觅食行为&#xff0c;具有搜索速度快&#xff0c;搜索能力强&#xff0c;能够有效平衡…

Windows已经安装了QT 6.3.0,如何再安装一个QT 5.12

要在Windows上安装Qt 5.12&#xff0c;您可以按照以下步骤操作&#xff1a; 下载Qt 5.12&#xff1a;访问Qt官方网站或其他可信赖的来源&#xff0c;下载Qt 5.12的安装包。 下载安装地址 下载安装详细教程 安装问题点 qt安装时“Error during installation process(qt.tools…