• springBoot源码汇总


    SpringFactoriesLoader

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

     ClassLoader classLoader = this.getClassLoader();
            Set names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
            List instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
            AnnotationAwareOrderComparator.sort(instances);
            return instances;
    
    • 1
    • 2
    • 3
    • 4
    • 5

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

    List loadFactoryNames(Class factoryType, @Nullable ClassLoader classLoader)
    
    • 1

    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);
                }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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
    
    • 1

    org.springframework.beans.BeanUtils#instantiateClass

     instantiateClass(Constructor ctor, Object... args) 
    
    • 1

    自定义函数入参

    函数参数调用方

    示例位置:SpringApplicationRunListeners#starting

     this.doWithListeners("spring.boot.application.starting", (listener) -> {
                listener.starting(bootstrapContext);
            }, (step) -> {
                if (mainApplicationClass != null) {
                    step.tag("mainApplicationClass", mainApplicationClass.getName());
                }
            });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    函数参数定义方

       private void doWithListeners(String stepName, Consumer listenerAction, Consumer stepAction) {
            StartupStep step = this.applicationStartup.start(stepName);
            this.listeners.forEach(listenerAction);
            if (stepAction != null) {
                stepAction.accept(step);
            }
            step.end();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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);
        }
        ……
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    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 {
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

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

  • 相关阅读:
    计算机网络原理 网络层
    Linux 进程间通信---信号
    Java毕业设计-科研工作管理系统
    java中@Qualifier注解的作用?
    Vue快速入门
    【JavaWeb从入门到实战】揭开JDBC的神秘面纱之上篇
    函数题39 习题10-11 有序表的增删改查操作《C语言程序设计(第4版)》题目集
    【学习笔记】MySQL(Ⅲ)
    测试开发【Mock平台】11基础:拦截器服务实现(二)事半功倍的WebMvcConfigurer
    StarRocks 运维工具 StarGo
  • 原文地址:https://blog.csdn.net/tian830937/article/details/132923822