自定义springboot actuator endpoint及原理解析

本文介绍了SpringBootActuator作为系统监控工具的作用,以及如何通过SpringBootAdmin进行可视化管理。详细阐述了自定义Endpoint的实现过程,包括使用@Endpoint、@Component、@ReadOperation和@Selector注解。同时解析了SpringBoot如何自动装配和识别自定义Endpoint,通过WebEndpointDiscoverer和WebMvcEndpointHandlerMapping将Endpoint转换为Web接口。

springboot actuator是springboot官方提供的系统信息探测器,用于获取系统状态和业务监控等信息。springboot admin封装了springboot actuator,常用于业务系统的可视化监控管理及报警。

springboot actuator endpoint是使用spring mvc通过http方式对外提供服务的web端点,官方提供了有HealthEndpoint、InfoEndpoint等web端点,来提供系统的健康状态或其他系统信息。当需要自己的endpoint时,该如何设计呢。

  • 自定义springboot actuator endpoint

主要需要@Endpoint、@Component、@ReadOperation、@Selector四个注解即可搞定,代码示例如下:

@Endpoint(id = "customPoint")
@Component
public class CustomEndPoint {

    @ReadOperation
    public String getCustom(@Selector String name) {
        return "MyName is ." + name;
    }
}

自定义endpoint如此简单,那它是如何被springboot识别,并转换成spring mvc的web接口的呢。

  • 原理解析

springboot最强大的功能即自动装配,它可以主动去发现endpoint,首先看下HealthEndpoint的自动装配及解析过程,spring-boot-starter-actuator是官方提供的starter,包含spring-boot-actuator-autoconfigure和actuator本身逻辑两部分,其中autoconfigure中spring.factories中配置了诸多自动配置类,这些类在springboot启动时,都会因为starter机制,而被实例化,这里也正是actuator被启动的开端,其中就包括HealthEndpointAutoConfiguration,该类在被实例化前会因@Import注解先实例化HealthEndpointConfiguration,接着即创建HealthEndpoint,并将该实例加入spring容器,源码如下:

@Configuration
@EnableConfigurationProperties({ HealthEndpointProperties.class, HealthIndicatorProperties.class })
@AutoConfigureAfter(HealthIndicatorAutoConfiguration.class)
@Import({ HealthEndpointConfiguration.class, HealthEndpointWebExtensionConfiguration.class })
public class HealthEndpointAutoConfiguration {
}

@Configuration
class HealthEndpointConfiguration {

	@Bean
	@ConditionalOnMissingBean
	@ConditionalOnEnabledEndpoint
	public HealthEndpoint healthEndpoint(ApplicationContext applicationContext) {
		return new HealthEndpoint(HealthIndicatorBeansComposite.get(applicationContext));
	}
}

到此,相关endpoint即被实例化和加入spring容器中了,那么自定义的endpoint并没有自动装配机制,它是如何被加入spring容器中的呢,自定义自动装配也行,@Component也能搞定,接下即为转换为web端点的过程:

WebEndpointAutoConfiguration自动配置类会创建bean:WebEndpointDiscoverer、PathMappedEndpoints,其中pathMappedEndpoint会调用WebEndpointDiscoverer中的getEndpoints来初始化WebEndpointDiscoverer中的endpoint集合,核心代码即为从spring容器中获取包含@Endpoint注解的类,代码如下:

String[] beanNames = BeanFactoryUtils.beanNamesForAnnotationIncludingAncestors(this.applicationContext, Endpoint.class);

这样WebEndpointDiscoverer即找到了所有的endpoint,WebMvcEndpointManagementContextConfiguration自动装配类会创建WebMvcEndpointHandlerMapping实例,从该类的类图可以看到其最终实现了InitializingBean接口,该接口为springboot的功能扩展点,即在类的属性设置之后,会回调afterPropertiesSet方法,该方法的逻辑即为转换为web接口的过程,具体逻辑可参考spring web的源码分析。

 

<think>我们正在从代码层面解析Spring Boot框架的优点和实现原理。根据引用,我们知道Spring Boot是为了简化Spring应用的初始搭建和开发过程,采用约定大于配置的思想,减少样板化配置,并集成了大量第三方库的配置。 从代码层面,我们可以关注以下几个关键点: 1. 自动配置(Auto-Configuration) 2. 起步依赖(Starter Dependencies) 3. 嵌入式Web服务器(Embedded Web Server) 4. Actuator(监控和管理端点) 下面我们将逐一解析: ## 1. 自动配置(Auto-Configuration) Spring Boot的自动配置是其核心特性之一。它基于类路径上存在的类、已存在的Bean定义以及属性设置自动配置Spring应用。 **实现原理**: - Spring Boot在启动时会扫描类路径下的`META-INF/spring.factories`文件,该文件中定义了大量的自动配置类(如`org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration`)。 - 这些自动配置类使用`@Conditional`注解(如`@ConditionalOnClass`、`@ConditionalOnMissingBean`等)来决定是否生效。例如,当类路径下存在`Servlet`类时,才会加载Web相关的自动配置。 - 自动配置类中定义了默认的Bean,当没有用户自定义的Bean时,这些默认Bean就会被创建。 **示例代码片段**: 在`WebMvcAutoConfiguration`中,我们可以看到如下代码: ```java @Configuration @ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class }) @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class }) public class WebMvcAutoConfiguration { // ... 内部配置类 @Bean @ConditionalOnMissingBean public InternalResourceViewResolver defaultViewResolver() { // 默认视图解析器 } } ``` 上述代码表示:当应用是Servlet Web应用,且类路径存在Servlet、DispatcherServlet和WebMvcConfigurer,且用户没有自定义`WebMvcConfigurationSupport`类型的Bean时,该自动配置类才会生效。 **优点**:开发者无需编写大量配置,只需引入相关依赖,Spring Boot就会自动配置好这些组件。 ## 2. 起步依赖(Starter Dependencies) 起步依赖是一组方便的依赖描述符,通过一个依赖即可获得开发某类应用所需的所有相关依赖。 **实现原理**: - 起步依赖本质上是一个Maven项目对象模型(POM),它定义了该功能所需的所有依赖,并对这些依赖的版本进行管理。 - 例如,`spring-boot-starter-web`起步依赖包含了Spring MVC、Tomcat、Jackson等开发Web应用所需的依赖。 **优点**:避免了依赖之间的版本冲突,简化了依赖管理。 ## 3. 嵌入式Web服务器 Spring Boot支持嵌入式Tomcat、Jetty和Undertow服务器,无需将应用部署到外部服务器。 **实现原理**: - Spring Boot通过自动配置来初始化嵌入式Web服务器。例如,当类路径下存在`Tomcat.class`时,会自动配置Tomcat服务器。 - 在启动过程中,Spring Boot会创建`ServletWebServerApplicationContext`,并启动嵌入式的Web服务器。 **代码示例**: 在`ServletWebServerFactoryAutoConfiguration`中,自动配置了嵌入式Web服务器工厂: ```java @Configuration @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE) @ConditionalOnClass(ServletRequest.class) @ConditionalOnWebApplication(type = Type.SERVLET) @EnableConfigurationProperties(ServerProperties.class) @Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, ServletWebServerFactoryConfiguration.EmbeddedTomcat.class, ServletWebServerFactoryConfiguration.EmbeddedJetty.class, ServletWebServerFactoryConfiguration.EmbeddedUndertow.class }) public class ServletWebServerFactoryAutoConfiguration { // ... } ``` 该配置类根据类路径下存在的类来选择具体的嵌入式服务器(Tomcat、Jetty或Undertow)。 **优点**:简化了部署,可直接运行一个独立的Jar包。 ## 4. Actuator Spring Boot Actuator提供了对应用进行监控和管理的能力。 **实现原理**: - Actuator通过一系列的端点(endpoints)暴露监控信息,如`/health`、`/info`、`/metrics`等。 - 这些端点的实现基于自动配置,通过`@Endpoint`注解定义。 **示例代码**: ```java @Endpoint(id = "health") public class HealthEndpoint { private final HealthIndicator healthIndicator; public HealthEndpoint(HealthIndicator healthIndicator) { this.healthIndicator = healthIndicator; } @ReadOperation public Health health() { return this.healthIndicator.health(); } } ``` 在自动配置中,会创建这个Endpoint的Bean。 **优点**:方便监控应用运行状态,进行运维管理。 总结:Spring Boot通过自动配置、起步依赖、嵌入式服务器和Actuator等特性,简化了Spring应用的开发和部署。这些特性在代码层面通过条件化配置、起步依赖POM以及嵌入式服务器的自动配置等实现。 根据上述解析,我们生成相关问题如下: </think>下面从代码层面解析Spring Boot框架的优点及实现原理,结合其核心特性进行分析: ### 一、核心优点在代码中的体现 1. **自动配置(Auto-Configuration)** ```java @SpringBootApplication // 核心注解 public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` - **实现原理**: - `@SpringBootApplication` 组合了 `@EnableAutoConfiguration`,触发 `spring-boot-autoconfigure.jar` 中的配置逻辑 - 通过 `META-INF/spring.factories` 加载 150+ 自动配置类(如 `DataSourceAutoConfiguration`) - 使用 `@Conditional` 注解实现条件装配(示例): ```java @Configuration @ConditionalOnClass(DataSource.class) // 类路径存在DataSource时生效 @ConditionalOnMissingBean(DataSource.class) // 容器无自定义DataSource时生效 public class DataSourceAutoConfiguration { @Bean public DataSource dataSource() { // 自动创建默认数据源 } } ``` 2. **起步依赖(Starter POMs)** ```xml <!-- pom.xml示例 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- 隐含传递tomcat/jackson/validation等依赖 --> </dependency> ``` - **实现原理**: - Starter本质是Maven POM文件,通过 `<dependencies>` 聚合关联依赖 - 遵循 `spring-boot-dependencies` 定义的版本仲裁机制 3. **嵌入式容器** ```java // 内嵌Tomcat启动代码片段(TomcatWebServer.java) public void start() throws WebServerException { this.tomcat.start(); // 直接启动Tomcat实例 } ``` - **优点**:无需外部Web容器,通过 `java -jar` 直接运行 ### 二、核心实现原理 1. **启动流程源码解析** ![](https://example.com/springboot-startup.png)[^1] ```java // SpringApplication.run() 关键步骤 public ConfigurableApplicationContext run(String... args) { 1. 初始化ApplicationContextInitializer 2. 创建ApplicationContext (AnnotationConfigServletWebServerApplicationContext) 3. 执行@Bean方法注册 4. 调用自动配置入口:AutoConfigurationImportSelector.selectImports() 5. 启动嵌入式Web服务器:ServletWebServerApplicationContext.refresh() } ``` 2. **条件装配机制** | 注解 | 作用 | 代码示例 | |---|---|----| | `@ConditionalOnClass` | 类路径存在指定类时生效 | `@ConditionalOnClass(RedisTemplate.class)` | | `@ConditionalOnProperty` | 配置属性匹配时生效 | `@ConditionalOnProperty(name="redis.enable")` | | `@ConditionalOnWebApplication` | Web环境生效 | `@ConditionalOnWebApplication(type=SERVLET)` | 3. **配置加载顺序**(源码:`ConfigFileApplicationListener`) ```java // 配置源加载优先级 List<PropertySource<?>> sources = Arrays.asList( new PropertySource("application.yml"), new PropertySource("application.properties"), new PropertySource("命令行参数") ); ``` ### 三、代码层优势总结 1. **零XML配置**:基于JavaConfig的配置方式取代传统XML ```java @Configuration public class MyConfig { @Bean // 替代<bean>标签 public MyService myService() { return new MyServiceImpl(); } } ``` 2. **健康检查内置**(通过Actuator) ```java // 自定义健康指示器 @Component public class CustomHealthIndicator implements HealthIndicator { @Override public Health health() { return Health.up().withDetail("version", "1.0").build(); } } ``` 3. **外部化配置支持** ```java @Value("${server.port}") private int port; // 自动注入配置值 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值