Spring中BeanDefinitionRegistryPostProcessor接口 -【Spring底层原理】

}

// 待注入的bean

public class User {

}

// BeanDefinitionRegistryPostProcessor实现类

@Component

public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {

System.out.println(“MyBeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry”);

System.out.println(“bean的数量:”+ beanDefinitionRegistry.getBeanDefinitionCount());

// 通过bean的构建器生成rootbean

AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();

beanDefinitionRegistry.registerBeanDefinition(“hello”,beanDefinition);

}

public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

System.out.println(“MyBeanDefinitionRegistryPostProcessor#postProcessBeanFactory”);

System.out.println(“bean的数量:” + configurableListableBeanFactory.getBeanDefinitionCount());

}

}

// 配置类

@Configuration

@ComponentScan(“postprocessor”)

public class AppConfig {

}

可以看到输出结果如下,从中我们可以看出:

  • 先执行postProcessBeanDefinitionRegistry方法,获取到IOC容器中bean的数量为7
  • 然后给Registry里面注册一个hello
  • 再执行postProcessBeanFactory方法,由于上面又注册了一个,所以这里获取到IOC容器中bean的数量为8
  • 等BeanDefinitionRegistryPostProcessor里面的方法都执行完后,再执行BeanFactoryPostP

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

rocessor里面的方法

image-20210319140530528

三、源码分析

同样,我们通过Debug的方式来分析源码,在postProcessBeanDefinitionRegistry方法处打个断点,启动断点调试,根据方法调用栈来进行跟踪:

image-20210319154228551

通过查看方法调用栈,可以作出如下分析:

  • 启动IOC容器调用refresh方法
  • 再依次调用invokeBeanFactoryPostProcessors()——>invokeBeanDefinitionRegistryPostProcessors()方法
  • 在invokeBeanDefinitionRegistryPostProcessors方法中获取到currentRegistryProcessors参数

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {

// 获取到BeanDefinitionRegistryPostProcessor组件

postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

var16 = postProcessorNames;

var9 = postProcessorNames.length;

for(var10 = 0; var10 < var9; ++var10) {

ppName = var16[var10];

if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {

// 获取currentRegistryProcessors参数

currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));

processedBeans.add(ppName);

}

}

while(reiterate) {

reiterate = false;

postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

String[] var19 = postProcessorNames;

var10 = postProcessorNames.length;

for(int var26 = 0; var26 < var10; ++var26) {

String ppName = var19[var26];

if (!processedBeans.contains(ppName)) {

currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));

processedBeans.add(ppName);

reiterate = true;

}

}

sortPostProcessors(currentRegistryProcessors, beanFactory);

registryProcessors.addAll(currentRegistryProcessors);

// 1.在这个方法里面触发postProcessBeanDefinnitionRegistry

invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());

currentRegistryProcessors.clear();

}

// 2.在这个方法里面触发postProcessBeanFactory方法

invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);

invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);

// 3.在这个方法里面触发postProcessorBeanFactory方法

invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);

}

从源码可以看到:

  • 先获取BeanDefinitionRegistryPostProcessor组件
  • 再按照一定规则(如优先级)加入到currentRegistryProcessors数组中
  • currentRegistryProcessors作为参数传给invokeBeanDefinitionRegistryPostProcessors方法,最后在这个方法执行
  • 下图可以看到此时已经将自己写的MyBeanDefinitionRegistryPostProcessor组件给获取到了

image-20210319155522363

【1】触发BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry

进入invokeBeanDefinitionRegistryPostProcessors方法,可以看到,在这里获取到组件并触发了postProcessBeanDefinitionRegistry:

private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {

Iterator var3 = postProcessors.iterator();

while(var3.hasNext()) {

BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor)var3.next();

StartupStep var10000 = applicationStartup.start(“spring.context.beandef-registry.post-process”);

postProcessor.getClass();

StartupStep postProcessBeanDefRegistry = var10000.tag(“postProcessor”, postProcessor::toString);

// 触发postProcessBeanDefinnitionRegistry

postProcessor.postProcessBeanDefinitionRegistry(registry);

postProcessBeanDefRegistry.end();

}

}

【2】触发BeanDefinitionRegistryPostProcessor组件的BeanFactoryPostProcessor#postProcessBeanFactory

在invokeBeanDefinitionRegistryPostProcessors方法执行完后,通过invokeBeanFactoryPostProcessors方法执行postProcessBeanFactory,点进源码进行查看:

private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

Iterator var2 = postProcessors.iterator();

while(var2.hasNext()) {

BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();

StartupStep var10000 = beanFactory.getApplicationStartup().start(“spring.context.bean-factory.post-process”);

postProcessor.getClass();

StartupStep postProcessBeanFactory = var10000.tag(“postProcessor”, postProcessor::toString);

// 执行postProcessBeanFactory

postProcessor.postProcessBeanFactory(beanFactory);

postProcessBeanFactory.end();

}

}

【3】触发其他组件的BeanFactoryPostProcessor#postProcessBeanFactory

private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

Iterator var2 = postProcessors.iterator();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot Actuator是一个用于监控和管理Spring Boot应用程序的模块,它提供了一组内置的端点(endpoints)和监控指标(metrics)来帮助开发人员了解和管理应用程序的运行状态。下面是spring-boot-starter-actuator底层实现原理的简要说明: 1. 自动配置:spring-boot-starter-actuator模块通过自动配置机制与Spring Boot应用程序集成。它依赖于Spring Boot的自动配置功能,根据类路径的依赖项以及应用程序的配置来自动配置Actuator模块。 2. 端点(Endpoints):Actuator通过提供一系列预定义的端点,使开发人员能够获取与应用程序相关的信息。例如,/health端点用于检查应用程序的健康状况,/info端点用于获取应用程序的自定义信息,/metrics端点用于查看应用程序的指标数据等等。这些端点可以通过HTTP请求访问,并返回相应的数据。 3. 端点暴露:Actuator模块默认会将一些常用的端点暴露出来,以便可以通过HTTP请求访问它们。你也可以通过配置来选择性地启用或禁用具体的端点,并可以自定义端点的访问路径。 4. 监控指标(Metrics):Actuator还提供了一套监控指标,用于测量和记录应用程序的运行状态和性能数据。它可以集成多种监控系统(如Prometheus、Graphite等),并提供了一个统一的接口来访问这些指标。Actuator会自动收集和公开一些常用的指标,同时也支持自定义指标的收集和公开。 5. 扩展性:Actuator模块提供了扩展机制,使开发人员可以自定义和添加自己的端点和指标。你可以通过实现特定的接口或注解来创建自定义端点,并使用Actuator的扩展点机制将其集成到应用程序。 总之,spring-boot-starter-actuator底层实现原理主要是通过自动配置、点和指标的暴露,以及与监控系统的集成来提供对Spring Boot应用程序的监控和管理功能。它的设计目标是简化开发人员对应用程序运行状态的监控和管理,并提供了一套易于使用和扩展的接口

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值