扎心了,老铁,程序出了小差,请重新再试
重新再试

首页> 网络架构> 网络图

SpringBoot启动流程

热门
SpringBoot启动流程
SpringBoot 启动流程,欢迎点赞 {从所有spring.factory实例化获取SpringApplicationRunListener列表到SpringApplicationRunListeners 然后starting,使用SpringAppilcationBuilder创建了新的SpringApplication,调用run()方法,按照spring容器构建流程,生成了父容器(Bootstrap容器)AnnotationConfigApplicationContext,随后放入AncestorInitializer,在触发(应用容器)执行ApplicationContextInitializer时,设置为应用容器的父容器。
(run()方法构建容器时还会触发BootstrapApplicationListener,由于构建前environment,已经设置了名:bootstrap的PropertySource,检测这个变量如果存在,就返回,而不会死循环无限构建)

解析https://blog.csdn.net/wangwei19871103/article/details/105728553/
,prepareContext(),doGetBean,applyPropertyValues():填充字段属性值,invokeAwareMethods(),1.初始化ConfigurableEnvironment:MutablePropertySources,主要是系统变量和环境变量

,触发BootstrapApplicationListener
,EventPublishingRunListener中是空方法,未实现,取到,(√)GenericApplicationContext.refreshBeanFactory()只设置了serializationId,DefaultListableBeanFactory beanFactory = createBeanFactory();,
Object singletonObject = this.singletonObjects.get(beanName);
//继续从单例池map中获取还是获取不到
beforeSingletonCreation(beanName);
//将beanName放到Set(singletonsCurrentlyInCreation)中,这个set为正在创建的beanName集合
singletonObject = singletonFactory.getObject();
//获取不到会执行singletonFactory的getObject()方法,这个方法里面有一个牛逼的方法createBean

,refresh(context);,实例化Bean:封装成BeanWraper,循环引用总结:spring-framework默认支持循环引用的,因为在第一次调用getSingleton的时候第二个参数写死为true,还有一个地方就是第二次调用getSingleton的时候,最终会调用ObjectFactory的getObject()方法,这个方法中只有一个方法createBean,这个方法会调用doCreateBean方法,这个方法中会进行是否支持循环引用,这个参数:allowCircularReferences,并且这个参数默认为true,这两个true是说明spring默认支持循环依赖的最好的证明;详细说明一下这个过程:如果A依赖B,并且B依赖A,这个循环引用的过程是这样的:实例化A,当执行到第一个getSingleton的时候,先从单例池singletonObjects中获取一次,这个时候肯定获取不到,接着判断是否正在创建的Set(singletonCurrentlyInCreation)集合中,这个时候在这个set中也没有,接下来就进入第二个getSington方法,这个方法会先在正在创建的Set(singletonCurrentlyInCreation)中放入一个该beanName,接下来会执行ObjectFactory的getObject(),这个getObject()中有一个createBean()方法,这个方法的重点是doCreateBean,doCreateBean中先将对象的工厂类放入到Map(singletonFactories)中,接着进行属性注入populateBean,发现需要注入B,这个时候会调用getBean,也会调用第一次getSingleton,这个时候B也获取不到,进行第二次getSingleton,一样的逻辑,将B的beanName放到正在创建的Set中,并且将B的工厂类放入到Map中,接着进行属性注入populateBean,发现需要注入A,就需要getBean(),继续进入第一次getSingleton,单例池中还是没有,但是A正在创建的条件成立,接下来从earlySingletonObjects中get,这个时候还是获取不到,这个时候会从singletonFactories中将A的工厂拿出来,生成A对象,这个时候就会把这个A对象注入到B中,B的bean生成之后放入到单例池singletonObjects中,接着A就可以注入B,接着A的bean再放入单例池singletonObjects中,至此,循环引用得以解决。为什么spring要设计earlySingletonObjects这个map存储bean呢?为什么singletonFactories存的是对象的工厂,,是因为在生成bean的时候需要对bean进行aop等改造的操作,所以需要用到工厂,生成的bean放入到earlySingletonObjects中是bean已经从工厂中获得了,如果有的类还需要这个bean就没有必要从工厂中再次获得了,毕竟从map中直接获取bean比在工厂中获取快的多。

,触发ApplicationContext准备好了的通知listeners.contextPrepared(context);,bindToSpringApplication(environment);,load(context, sources.toArray(new Object[0])),在父容器时,当前类postProcessEnvironment()解析了默认or指定位置名为bootstrap.(properties/xml/yml) 配置文件,为父容器Environment中添加了诸多PropertySources,,最后合并到子容器Environment中;
 在执行子容器ConfigFileApplicationListener的这个方法时,才开始解析默认or指定位置的application配置文件,getSpringFactoriesInstances,configureEnvironment(environment, applicationArguments.getSourceArgs());,prepareBeanFactory(beanFactory);,AnnotationConfigApplicationContext实现,里面的逻辑
,1,postProcessBeanFactory(beanFactory)(AnnotationConfigApplicationContext是空实现),同时构造方法中实例化 new AnnotatedBeanDefinitionReader(this); 
 new ClassPathBeanDefinitionScanner(this);,initMessageSource():初始化注册一个名为messageSource的 DelegatingMessage Source单例对象,并赋给AbstractApplicationContext(初始化国际化信息源),afterRefresh():空方法,1.设置环境激活的profile
2.判断设置两个propertySource:defaultProperties、springApplicationCommandLineArgs,触发了AutowiredAnnotationBeanPostProcessor的执行,注入依赖,ConfigurationClassPostProcessor在此时会被执行,去解析@Configuration @Bean @ComponentScan @Import @ImportResource(加载XML等形式中的Bean)注解形式指定的Class及其父类,注入容器,从所有spring.factory
1.实例化ApplicationContextInitializer(扩展点)
2.实例化ApplicationListener
,onRefresh():启动容器这一步没操作,应用容器在一步创建启动了tomcat(或jetty...)容器,prepareContext(context, environment, listeners, applicationArguments,
printedBanner),处理Autowire依赖的PropertyValue,context.registerShutdownHook(),第一次进入getSingleton(),getBeanFactory();获取GenericApplicationContext内部的DefaultListableBeanFactory对象,new SpringApplication(),postProcessApplicationContext(context),触发了EnvironmentPostProcessor执行,根据webApplicationType实例化:ConfigurableApplicationContext,默认对象是AnnotationConfigApplicationContext,父类AbstractApplicationContext构造方法中实例化 PathMatchingResourcePatternResolver(this),finishBeanFactoryInitializatio():实例化所有剩余的(非lazy-init)单例。触发所有非懒加载的单例bean初始化(即应用中自定义的各种controller、service等Bean的实例化初始化),构造时,初始化,BeanPostProcessor的五大接口https://www.cnblogs.com/zhangjianbin/p/10059191.html,X,容器加入new ApplicationListenerDetector(this),refreshContext():最重要的流程,初始化BeanDefinitionLoader,加载的是SpringApplication的primarySources、sources字段中的类注册进容器,在父级容器(AnnotationConfigApplicationContext)这个阶段sources是spring.factories中的BootstrapConfiguration类,子容器中这里sources是main()方法的启动类,为什么需要三个map呢?先来了解这三个map到底都缓存了什么
    * 第一个map singletonObjects 存放的单例的bean
    * 第二个map singletonFactories 存放的临时对象的工厂类(没有完整springBean生命周期的对象的工厂类)
    * 第三个map earlySingletonObjects 存放的临时对象(没有完整springBean生命周期的对象) 
,loadBeanDefinitions(beanFactory);,ConfigFileApplicationListener,顺序执行了
BeanNameAware、
BeanClassLoaderAware、
BeanFactoryAware 的set方法,触发ApplicationContextAwareProcessor,顺序执行了:
EnvironmentAware, EmbeddedValueResolverAware,
ResourceLoaderAware,  ApplicationEventPublisherAware,  MessageSourceAware, 
ApplicationContextAware的set方法,上层大致流程,initApplicationEventMulticaster():初始化一个SimpleApplicationEventMulticaster如果容器中没有的话,1.SpringFactoriesLoader.loadFactoryNames()
从classpath下META-INF/spring.factories获取所有指定的类名,并缓存,
|垂直关系|应用容器| 水平关系|启动容器|类型|
|  :----  |  :----  |  :----  |  :----  |  :----  |
|内置子容器|serializationId:***-***-***(DefaultListableBeanFactory): |子 --> 父|serializationId: application (DefaultListableBeanFactory)|BeanFactory|
|外置容器|id:application-1 (AnnotationConfigServletWebServerApplicationContext) | 子 --> 父| id: bootstrap (AnnotationConfigApplicationContext)|ApplicationContext| 
  
1、父子容器的关系就行内部类的关系一样。子容器能得到父容器的Bean,但是父容器得不到子容器的Bean
2、父子容器中,属性值都不是互通的。@Value注入的时候需要注意一下子~
,initMethod,getSingleton(beanName):从三个缓存中获取,同时父类GenericApplicationContext构造方法中实例化 beanFactory = DefaultListableBeanFactory,发布最终事件:ContextRefreshedEvent, AnnotatedBeanDefinitionReader实例化时AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)初始化了若干RootBeanDefinition,。。。,createApplicationContext(),其他ApplicationContext最终实现,里面的逻辑
,进入createBean,DefaultSingletonBeanRegistry,2.createSpringFactoriesInstances
获取类名后,反射创建对象,prepareRefresh():设置容器开启启动时间、状态、初始化propertySources如果有、验证Environment属性,第二次进入getSingleton(),prepareEnvironment(),beanFactory.preInstantiateSingletons();,发布ApplicationStartedEvent,容器,getBean(beanName);,待理解,注册BeanNameGenerator的单例bean(if判断跳过了)
设置context的classloader(if判断跳过了)
,createApplicationContext,getRunListeners, BeanPostProcessor.postProcessAfterInitialization(),初始化了:
ConfigurationClassPostProcessor(处理@Configuration@Bean)
AutowiredAnnotationBeanPostProcessor(处理@Autowired@Value@Inject)
RequiredAnnotationBeanPostProcessor(处理@Required)
CommonAnnotationBeanPostProcessor(处理@PostConstruct@PreDestroy@Resource)
PersistenceAnnotationBeanPostProcessor(要存在JPA)
EventListenerMethodProcessor(处理@EventListener)
,
if (earlySingletonExposure) {
   addSingletonFactory(beanName, new ObjectFactory<Object>() {
    @Override
    public Object getObject() throws BeansException {
     return getEarlyBeanReference(beanName, mbd, bean);
    }
   });
}
//如果支持循环依赖,则将单例对象工厂放入到Map(SingletonFactories)中,
并且将beanName放到set(registerSinglentons)中,当需要的时候从map中取出factory.getObject就可以得到对象
,执行BeanDefinitionRegistryPostProcessor(先PriorityOrdered,再Ordered),refreshContext(context),DefaultListableBeanFactory    761,populateBean():使用BeanDefination中的属性值填充给定BeanWrapper中的Bean实例,getBean(),AbstractAutowireCapableBeanFactory   483,InstantiationAwareBeanPostProcessor.postProcessPropertyValues(),applyInitializers(context):遍历执行ApplicationContextInitializer,进入getBean(),run(),判断,Bean类型是否是指定类型,context.registerShutdownHook():注册容器关闭钩子,第二次进入getSingleton的逻辑:
1,先从单例池map中获取,如果获取不到,则将beanName 放到singletonsCurrentlyInCreateion的Set中,并执行singletonFactory.getObject(),即就是执行createBean方法,createBean方法就是:如果支持循环依赖,则将该单例对象工厂放入到Map(SingletonFactories)中,并且将beanName放到set(registerSinglentons)中,当需要的时候从map中取出factory.getObject就可以得到对象,到此第二个getSingleton的逻辑就结束了,返回这个对象
,容器注入environment、systemProperties、systemEnvironment单利bean,AbstractBeanFactory,printBanner()(打印banner), BeanPostProcessor.postProcessBeforeInitialization(),createBean(beanName, mbd, args);,触发,PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()),InitializingBean,registerListeners():除了容器启动时spring.factories已有的,把应用容器子容器中新加的ApplicationListener,添加进应用容器的ApplicationEventMulticaster对象中,prepareEnvironment(listeners,
applicationArguments);,MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),Object beanInstance = doCreateBean(beanName, mbdToUse, args);,代理对象就是在这里创建的,如果需要的话:
AnnotationAwareAspectJAutoProxyCreator中的postProcessAfterInitialization方法会被触发创建代理类
,initializeBean(),AbstractRefreshableApplicationContext.refreshBeanFactory(),AbstractBeanFactory    306,
getSingleton(beanName);
//这是第一次创建getSingleton
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {}
//这是第二次进入getSingleton的重载方法
,AbstractApplicationContext.refresh();,getOrCreateEnvironment(),执行BeanFactoryPostProcessors方法(先BeanDefinitionRegistry PostProcessor,再普通的BeanFactoryPostProcessor,然后先是实现PriorityOrdered,再是实现Ordered的),InstantiationAwareBeanPostProcesso.postProcessAfterInstantiation(),设置ConfigurableApplicationContext的environment,afterRefresh(),invokeInitMethods(),没取到,
getSingleton(String beanName, boolean allowEarlyReference){
Object singletonObject = this.singletonObjects.get(beanName);
//这个方法是从单例池中获取,其实就是从ConCurrentHashMap中获取,没有就返回null
isSingletonCurrentlyInCreation(beanName)
//从Set(singletonsCurrentlyInCreation)中获取beanName,如果获取到说明该bean正在创建中
singletonObject = this.earlySingletonObjects.get(beanName);
//如果单例池中没有并且在创建中的话,试图从earlySingletonObjects的map中获取,如果还获取不到
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
//从第二次进入getSingleton的时候放入的singletonFactories的map中获取Factory,并通过getObject获得对象
this.earlySingletonObjects.put(beanName, singletonObject);
//将此对象当道earlySingletonObjects中一份
this.singletonFactories.remove(beanName);
//并且从singletonFactories中移除
}
,容器加入new ApplicationContextAwareProcessor(this),并beanFactory.ignoreDependencyInterface(忽略这个processor处理的Aware接口setter方法注入,registerBeanPostProcessors(beanFactory);注册相关BeanPostProcessor,供Bean生成前后调用。,customizeBeanFactory(beanFactory):设置允许循环引用&BeanDefination覆盖,ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(),  ConfigurableEnvironment environment = getOrCreateEnvironment(); 
,AbstractApplicationContext   867,AbstractAutowireCapableBeanFactory   542,listeners.environmentPrepared(environment);,finishRefresh():,invokeBeanFactoryPostProcessors(beanFactory);,doGetBean(),beanFactory.registerResolvableDependency(),此阶段明确指定了,如BeanFactory等接口的优先注入对象,而忽略他的其他实现,InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(),refreshBeanFactory();刷新内部的DefaultListableBeanFactory对象,设置serializationId}

文件简介

编号:13015

名称:SpringBoot启动流程

浏览数:16

收藏数:0

克隆数:0

作者:0

价格:3元

更新时间:2021-07-01 12:51:16

文件很好用,分享文件:

只需一步极速注册

63,195+文件在线编辑

云端同步我的设计

一键高清无水印下载

微信扫码立即登录
二维码失效
请点击刷新

微信和QQ是两个独立账号,账号信息不互通

距离今天活动结束仅剩
000000000毫秒
距离今天活动结束仅剩
000000000毫秒
距离今天活动结束仅剩
000000000毫秒
会员促销今天活动仅剩
000000000毫秒
距离今天活动结束仅剩
000000000毫秒