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的信息

java 复制代码
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后置处理器

java 复制代码
  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等

相关推荐
aisifang001 分钟前
SpringBoot Maven 项目 pom 中的 plugin 插件用法整理
spring boot·后端·maven
yashuk6 分钟前
SpringBoot中自定义Starter
java·spring boot·后端
独断万古他化28 分钟前
【抽奖系统开发实战】Spring Boot 活动模块设计:事务保障、缓存优化与列表展示
java·spring boot·redis·后端·缓存·mvc
prince051 小时前
SpringBoot + 多级缓存(Caffeine + Redis + 空值缓存):防穿透、防雪崩、低延迟三合一
spring boot·redis·缓存
indexsunny1 小时前
互联网大厂Java面试实战:从Spring Boot到微服务架构的音视频场景解析
java·spring boot·spring cloud·mybatis·spring security·jwt·flyway
spring2997921 小时前
Spring Boot 整合 Druid 并开启监控
java·spring boot·后端
014-code1 小时前
kafka + springboot快速入门
java·spring boot·分布式·kafka
李白的粉1 小时前
基于springboot的教师工作量管理系统
java·spring boot·毕业设计·课程设计·教师工作量管理系统·源代码
小王不爱笑1321 小时前
深入浅出 Docker 核心知识点,解锁容器化技术精髓
java·spring boot·docker
一棵树73512 小时前
Springboot项目常用工具对比总结
java·spring boot·后端