对象内存分配、springboot启动、循环依赖
2020-10-16 09:53:58 0 举报
对象内存分配、springboot启动、循环依赖
作者其他创作
大纲/内容
RuntimeBeanReference
监听器调用contextLoaded
pop
线程外内存分配
判断入参类型是否被@Component注解修饰或有继承该注解,是有的@Configuration@Import(BootstrapImportSelector.class)BootstrapImportSelectorConfiguration然后递归去找应该被加载的类
初始化sb应用加载spring.factories到内存,并缓存SpringFactoriesLoader.loadFactoryNames
确定应用启动主类用于加载容器注解依赖
S1
new SpringApplication
listeners
doGetBean获取到A的实例,将A放入二级缓存
执行顺序
后3个事件调用的是上下文的publishEvent()方法startedrunningfailed
prepareContext
创建子容器createApplicationContext()AnnotationConfigServletWebServerApplicationContext
alreadyCreated.add(beanName)
属性填充B bresolveValueIfNecessary()resolveReference()
调用load方法
createBeanInstance对象实例化
为工厂做一些准备工作prepareBeanFactory(beanFactory)
prepareContext()
listeners.environmentPrepared(environment)执行监听器环境准备好的回调
finishBeanFactoryInitialization()实例化并初始化剩余的单例对象
对bean工厂进行一些填充设置表达式解析器StandardBeanExpressionResolver#{}设置ResourceEditorRegistrar设置bean后置处理器ApplicationContextAwareProcessor用来设置各种aware属性,在before方法中处理配置忽略各种awareEnvironmentAware设置bean后置处理器ApplicationListenerDetector,监听器相关注册environment实例到单例缓存池singletonObjects注册systemProperties实例到单例缓存池singletonObjects
对象
BeanDefinitionValueResolver
比如将父容器设置到子容器设置关联
加载初始化器ApplicationContextInitializer
一级缓存没有,并且没有被标记为正在创建,不能进入二级缓存判断
getRunListeners(args)获取监听器并全部启动,从sp中加载类型为SpringApplicationRunListener的监听器配置到
addSingleton()将对象A放入一级缓存
registerBeanPostProcessors()注册Bean的后置处理器
3调用监听器的contextPrepared()
会调用父类GenericApplicationContext的构造器创建一个bean工厂beanFactory=DefaultListableBeanFactory
A
在方法prepareContext中执行初始化器,调用apollo初始化器,加载远程属性配置
s2
创建父容器完了之后加入初始化器AncestorInitializer用于将父容器和子容器建立关系,在子容器中加入CloseContextOnFailureApplicationListener监听器
listeners.contextLoaded(context)
栈分配
new
EventPublishingRunListener事件多播器,在容器创建过程中根据监听器关心的事件类型进行回调监听器的onApplicationEvent方法
1
org.springframework.context.annotation.internalConfigurationAnnotationProcessor找到ConfigurationClassPostProcessor
TLAB
ApplicationListener
3
populateBean对象A属性B b填充
addSingleton()将对象B放入一级缓存
调用匿名内部类方法
SimpleApplicationEventMulticaster
前4个事件是调用multicastEvent方法进多播
onApplicationEvent
registerListeners()注册监听器
线程本地
getSingleton传入的匿名内部类调用doCreateBean再次判断一级缓存是否有对象
AbstractAutowireCapableBeanFactory
doGetBean先从三级缓存获取B为空,标记正在创建markBeanAsCreated()
获取工厂beanFactory = obtainFreshBeanFactory()
GC年龄大于15(=15,markword,可配置)
FormApplication.main
doGetBean先从一级缓存获取标记正在创建
获取对象B的实例
2
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()
B实例化创建完成,返回A的创建过程
属性填充B bapplyPropertyValues
beanFactory.preInstantiateSingletons()对象构建
getBean()
onRefresh()调用web容器的初始化tomcat、jetty等
refreshContext()调用父类的方法,开始启动spring容器,容器启动12步
放入的ObjectFactory匿名内部类实现
ListenerRetriever
getSingleton()
循环依赖
类型转换服务ApplicationConversionService读取默认属性配置设置active_profile
SpringApplication.run
DefaultListableBeanFactory
SpringApplicationRunListeners
销毁
对象大小分析
否
starting
DefaultSingletonBeanRegistry
minorGC
B b
判断入参类型是否被@Component注解修饰或有继承该注解这里的入参是springboot的启动类应用程序定义的入口(比如FormApplication),并将主类的BeanDefinition加入到beanDefinitionMap中然后递归去找,应该被加载的注解
存活?
准备系统环境属性prepareEnvironment
addSingletonFactory放入三级缓存,beanName->ObjectFactory<?>
prepareRefresh()设置时间和容器状态设置环境变量验证必要参数设置之前加载的监听器new一个早期应用事件集合
old区
invokeBeanFactoryPostProcessors(beanFactory)按照顺序实例化并调用已经注册了的BeanFactoryPostProcessor,过程中会将需要的类都加载成BeanDefintion
initializeBean对象初始化
StandardEnvironment
finishRefresh()结束刷新、发布事件
创建并打印banner
7个方法对应ApplicationListener接口的方法startingenvironmentPreparedcontextPreparedcontextLoaded
启动计时
逃逸分析标量替换
监听器LoggingSystemShutdownListenerConfigFileApplicationListenerAnsiOutputApplicationListenerLoggingApplicationListenerClasspathLoggingApplicationListenerBackgroundPreinitializerDelegatingApplicationListenerRestartListenerParentContextCloserApplicationListenerClearCachesApplicationListenerFileEncodingApplicationListenerLiquibaseServiceLocatorApplicationListener
监听器调用contextPrepared
initMessageSource()国际化
initApplicationEventMulticaster()为容器初始化事件多波器
processConfigurationClass()根据注解进行递归扫描所有注解以及继承的注解扫描@Component扫描@PropertySource扫描@ComponentScans和ComponentScan扫描@Import扫描@ImportResource扫描@Bean的方法处理接口的默认方法
run
A创建完成
返回
populateBean对象B属性A a填充
refreshContext()执行父容器的加载12大步骤后面子容器的时候详细标注加载父容器的一些东西,比如consul的处理器
LoggingSystemShutdownListenerConfigFileApplicationListenerAnsiOutputApplicationListenerLoggingApplicationListenerClasspathLoggingApplicationListenerBackgroundPreinitializerDelegatingApplicationListenerRestartListenerParentContextCloserApplicationListenerClearCachesApplicationListenerFileEncodingApplicationListenerLiquibaseServiceLocatorApplicationListener
markBeanAsCreated一级缓存没有,并且没有被标记为正在创建,不能进入二级缓存判断
属性填充A aapplyPropertyValues
ConfigurationClassParser
调用对应事件方法并new一个对应事件的事件实例
注册单例缓冲池springApplicationArgumentsspringBootBanner设置允许覆盖bean定义
ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()
调用监听器的started事件执行ApplicationRunner执行CommandLineRunner调用监听器的running()事件
加载子容器应用启动监听器ApplicationListener
调用监听器,广播容器starting事件
GenericApplicationContext设置容器ID
eden
公共区域
从spring.factories加载异常报告器SpringFactoriesLoader.loadFactoryNames
为上下文设置环境属性设置类型转换器
线程内分配
SharedMetadataReaderFactoryContextInitializer加入BeanDefinition
B
类里有个ListenerRetriever类型的内部类变量用来装监听器
用于启动父容器,会再次调用SpringApplication.run()进行父容器进行构建,通过判断当前容器属性是否包含bootstrap,如果包含就不在启动再次启动,否则会拉起一个父容器,执行SpringApplication.run()父容器类型AnnotationConfigApplicationContext
FGC
BootstrapApplicationListener
AbstractBeanFactory
父类AbstractApplicationEventMulticaster
事件多播器SpringApplicationRunListener的实现类:EventPublishingRunListener实例化时,将监听器放入SimpleApplicationEventMulticaster,并且将后者作为前者的成员变量,后面广播事件时根据事件筛选监听器进行事件广播
开始自动装配过程invokeBeanDefinitionRegistryPostProcessors()
environmentPrepared
A a
4
调用初始化器
0 条评论
下一页