当前位置: 首页 > news >正文

springBoot源码汇总

SpringFactoriesLoader

示例位置 SpringApplication#getSpringFactoriesInstances
加载spring.factroies下的初始化类

 ClassLoader classLoader = this.getClassLoader();Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);AnnotationAwareOrderComparator.sort(instances);return instances;

说明:
SpringFactoriesLoader.loadFactoryNames 加载type为spring.factroies 下的 class的key值

List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader)

ClassUtils .BeanUtils

示例位置 SpringApplication#createSpringFactoriesInstances

  try {Class<?> instanceClass = ClassUtils.forName(name, classLoader);Assert.isAssignable(type, instanceClass);Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);T instance = BeanUtils.instantiateClass(constructor, args);instances.add(instance);} catch (Throwable var12) {throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, var12);}

ClassUtils.forName,name为加载类的全路径名称,通过ClassUtils.forName加载对应的类
通过 instanceClass.getDeclaredConstructor(parameterTypes); 表示传入无参的构造参数
示例此处的值为:new Class[0] ,

new Class[0]表示有零个元素的Class数组,即空数组,与传入null结果是一样的,都表示取得无参构造方法。
但是使用该方式可以避免抛出空异常。

BeanUtils.instantiateClass(constructor, args); 通过构造函数,入参实例化一个对象

org.springframework.util.ClassUtils#forName

public static Class<?> forName(String name, @Nullable ClassLoader classLoader) throws ClassNotFoundException, LinkageError

org.springframework.beans.BeanUtils#instantiateClass

 instantiateClass(Constructor<T> ctor, Object... args) 

自定义函数入参

函数参数调用方

示例位置:SpringApplicationRunListeners#starting

 this.doWithListeners("spring.boot.application.starting", (listener) -> {listener.starting(bootstrapContext);}, (step) -> {if (mainApplicationClass != null) {step.tag("mainApplicationClass", mainApplicationClass.getName());}});

函数参数定义方

   private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction, Consumer<StartupStep> stepAction) {StartupStep step = this.applicationStartup.start(stepName);this.listeners.forEach(listenerAction);if (stepAction != null) {stepAction.accept(step);}step.end();}
}

springboot 监听器扩展点混合使用

bean的生命周期和run的执行顺序

通过ApplicationContextInitializer 添加FactoryPostProcessor

主要依赖于bean的生命周期,context的加载、初始化、执行在FactoryPostProcessor扩展点之前执行,所以可以通过ApplicationContextInitializer扩展点动态添加扩展点。另一方面可以从beanFactory中拿到bean的信息和context的信息

class SharedMetadataReaderFactoryContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>, Ordered {public static final String BEAN_NAME = "org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory";SharedMetadataReaderFactoryContextInitializer() {}public void initialize(ConfigurableApplicationContext applicationContext) {BeanFactoryPostProcessor postProcessor = new SharedMetadataReaderFactoryContextInitializer.CachingMetadataReaderFactoryPostProcessor(applicationContext);applicationContext.addBeanFactoryPostProcessor(postProcessor);}……
}

CachingMetadataReaderFactoryPostProcessor实现了BeanDefinitionRegistryPostProcessor接口,而BeanDefinitionRegistryPostProcessor接口又继承了BeanFactoryPostProcessor所以BeanDefinitionRegistryPostProcessor本身就是一个BeanFactory后置处理器

  static class CachingMetadataReaderFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {private final ConfigurableApplicationContext context;CachingMetadataReaderFactoryPostProcessor(ConfigurableApplicationContext context) {this.context = context;}public int getOrder() {return -2147483648;}public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}
}

利用同样的思路可以添加动态的ApplicationListenter等

http://www.lryc.cn/news/174144.html

相关文章:

  • 代码随想录二刷day39
  • Spring面试题7:面试官:Spring是如何进行异常处理的呢?
  • 华为云云耀云服务器L实例评测|搭建您的私人影院网站
  • Solidity 小白教程:22. Call
  • mySQL 安装
  • 涛然自得周刊(第 10 期):搬到海岛生活是一种什么体验
  • pycharm中恢复原始界面布局_常用快捷键_常用设置
  • docker(7):实战--安装nginx并实现反向代理
  • day-61 代码随想录算法训练营(19)一刷完结撒花
  • C#中对泛型集合元素使用List.Sort()方法排序
  • 【项目】在线音乐播放器测试报告
  • [C++ 网络协议] 多线程服务器端
  • 宝塔部署node后使用pm2管理上传文件路径失效问题
  • postman-pre-request-scripts使用
  • uniapp Echart X轴Y轴文字被遮挡怎么办,或未能铺满整个容器
  • 学习路之PHP--laravel DingoApi
  • 项目篇——java文档搜索引擎
  • 5.2 磁盘CRC32完整性检测
  • 企业内部安全与风控管理图解
  • vscode基于cmake安装opencv库
  • Web 器学习笔记(基础)
  • uniapp中vue3使用uni.createSelectorQuery().in(this)报错
  • k8s-部署
  • Arduino驱动MMA7260三轴加速度传感器(惯性测量传感器篇)
  • 奇舞周刊第507期:通过 View Transition API 在状态之间添加丰富的过渡动画
  • 如何通过技术变现
  • 高效查询大量快递信息,轻松掌握技巧
  • iperf3: error - unable to connect to server: No route to host 但嵌入式Linux设备
  • OpenCV自学笔记十七:傅里叶变换
  • uniapp如何判断是哪个(微信/APP)平台