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等

相关推荐
_UMR_38 分钟前
springboot集成Jasypt实现配置文件启动时自动解密-ENC
java·spring boot·后端
蓝色王者1 小时前
springboot 2.6.13 整合flowable6.8.1
java·spring boot·后端
hashiqimiya3 小时前
springboot事务触发滚动与不滚蛋
java·spring boot·后端
因我你好久不见3 小时前
Windows部署springboot jar支持开机自启动
windows·spring boot·jar
无关86884 小时前
SpringBootApplication注解大解密
spring boot
追梦者1236 小时前
springboot整合minio
java·spring boot·后端
帅气的你6 小时前
Spring Boot 集成 AOP 实现日志记录与接口权限校验
java·spring boot
计算机毕设VX:Fegn08957 小时前
计算机毕业设计|基于springboot + vue在线音乐播放系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
计算机毕设VX:Fegn08957 小时前
计算机毕业设计|基于springboot + vue博物馆展览与服务一体化系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
帅气的你7 小时前
Spring Boot 1.x 接口性能优化:从 3 秒到 200 毫秒的实战调优之路
java·spring boot