Spring的流程超级超完整超级详细的整理---完整了解Spring启动的每个步骤--直击面试题
2024-07-24 09:54:05 4 举报
超级完整,超级详细的拆解了Spring启动的每个流程。深入每个步骤。面试再也不用担心Spring启动问题有不会的了
作者其他创作
大纲/内容
都是调用createBean 方法 流程是一致的
当前正在创建原型对象,直接报错
清空current
按照order的接口添加BPP到order 集合,区分出MergedBDPP
实例化剩余的单例对象preInstantiateSingletons
否
冻结所有的BD定义,确定BD不会被修改
添加到regularPostProcessors
一级、二级那都为空,但是在三级缓存中存在
遍历BPP 找到InstiaionAwareBPP 执行postProcessProperties这里也是涉及到元数据的
执行Ordered 的BDRegisterFPP的postProcessBeanDefinitionRegistry
ApplicationContentAware
这里允许添加更多BeanDefinition的注册
kernel
initApplicationEventMulticaster
refresh
Bean
createBeanInstance
初始不同的消息源,主要是针对多语言的国际化处理的
需要的话,添加到三级缓存,保存的是一个是ObjectFactory的 lambda 表达式删除二级缓存,后面的对象调用getObject方法的时候才会返回对象
BeanFactoryPostProcessor
设置转换器setConversionService
按名字组装成BDHolder
禁止使用临时加载器
判断循环依赖的bean 完成实例化
执行doscan 方法
遍历当前的BFPP,
直接执行postProcessBeanDefinitionRegistry
进行一次排序
对于AspectJ的支持
加锁,避免判断的过程出现数据不一致的情况
按未执行过的以及Ordered 排序的进行添加到current
transformedBeanName
byType按类型
添加到registerPostProcessor中去
存在
设置类加载
分别去解析xml中定义的一些属性 scope、init-method、replace-method、description 等已经报class的全路径,直接加载具体的信息就好了
1. 简单的实现了contex 功能,定义了一些模板要求子类来实现 initPropertySource 等等2、refresh 方法的具体实现3.特殊bean 的处理 BeanFactoryPostProcesser 、BeanPostProcesser、Listeners 注册4. MessageSource 也可以在这里被注册成一个Bean
prepareMethodOverrides 准备好lookup-method-meth,replace-method
添加到候选人Set中
填充属性
Springboot 在这里启动内助的Tomcat的
new XmlBeanDefinitionReader(beanFactory)
设置SPEL表达式的解析
obtainFreshBeanFactory
service
添加一个消息检测的BPP
执行BPP的before方法
ClassPathXmlApplicationContextclasspath:按包名路径解析默认按这个来解析的
afterPrototypeCreation(beanName);beanName从prototypesCurrentlyInCreation移除
AbstactRefreshableApplicationContext
DispatcherServlet
清理资源加载器
// 上下文刷新的通知,例如自动启动的组件\t\tgetLifecycleProcessor().onRefresh();
3.getBeanNamesForType拿BDRegisterPostProcessor
invokeInitMethodsbean的InitializingBean接口方法
registerListeners
注册nonOrderBPP到BeanFactory
一个通用的资源文件路径加载的管理类
设置环境变量到一级缓存
AbstactRefreshableConfigApplicationContext
默认的一些资源加载实现
finishRefresh
如果是实现了InstantiationAwareBeanPostProcessors 可以去修改bean的状态再设置属性之前
不存在
设置reader 的环境变量
getNamespaceHandlerResolver
invokeBeanFactoryPostProcess(beanFactory)
这里的话就把全部的BFPP的postProcessBeanFactory 方法 完成BD 修改
最后直接执行regularPostProcessors 的postProcessBeanDefinitionRegistry
遍历属性名称
最后也是通过getBean来获取这个属性值的,所以这里的嵌套会很深
按PriorityOrdered获取有优先级排序的current
这主要如果bean对象实现factorybean 接口的话,就会出现&beanName的情况,
getBeanNamesForType
遍历扫描 注解
// 发布最终事件\t\t// 新建ContextRefreshedEvent事件对象,将其发布到所有监听器。\t\tpublishEvent(new ContextRefreshedEvent(this));
BeanDefinitionRegistryPostProcessor是一个BFPP的子集,需要先执行
通过这里找出属性当中标记的注解
这个地方是最复杂的了,把剩下的bean 完成实例化和初始化
再注册一些自动装配需要用到的
byConstructor按构造器
获取beanNames
ApplicationEventPublisher
注册bean 和依赖bean的关系
invokeAwareMethodsAware接口处理器,调用BeanNameAware、BeanClassLoaderAware、beanFactoryAware
排序,然后注册beanFactory
LiveBeansView.registerApplicationContext(this);
getBean
添加一个BeanPostProcessorChecker
把非排序的BFPP添加到nonOrdered集合
父容器一般为空
二级缓存没有,并且允许循环依赖
也排序一下
添加Ordered排序BFPP 添加ordered集合
判断上是否存在于父容器中
就是获取META-IN/springfactories 当中的 handler 类
最核心的refresh方法
这里代码虽然很长,但是逻辑比较简单
这里找对对应的注解类,并且识别对应的注解的元数据,然后触发注入
实例化出来一个空对象
doLoadBeanDefinitions
initializeBean执行初始化
把没有排序的添加到nonOrdered 结合,区分出MergedBDPP
执行currentRegisterPostProcessor 中的postProcessBeanDefinitionRegistry
一级缓存没有,并且正在创建中
设置一个默认的数据源setParentMessageSource
AbstractPool
包装一个byType的描述对象
获取到document 对象
BeanFactory
实例化XMLBeanDefinitionReader允许子类自定义自己的reader 并且 通过loadBeanDefinitions 方法加载BD实现了xml 的loadBeanDefinitions 方法
new DelegatingMessageSource
Http11Processor
执行BPP的before方法applyBeanPostProcessorsBeforeInitialization
是否需要依赖检查
findParserForElement
2。通过getBeanNamesForType去拿BDRegisterPostProcessor
doRun的方法三次握手
prepareBeanFactory
populateBean属性填充
invoke
执行 applyMergedBeanDefinitionPostProcessors后置处理器修改合并bean的定义
设置默认的属性编辑器
main 方法new MyClassPathXmlApplicationContext(\"applicationContext.xml\");
也会通过BeanDefinitionUtis 注册BDholder 到BeanFactory
1. 先扫描 包名路径下的全部 .class 文件
annotation-config -> {AnnotationConfigBeanDefinitionParser@1390} @Resource 解析
new DefaultKListableBeanFactory
注册实现了MergedBeanDefinitionPostProcess的BPP ,会把前面已经注册的相同的BPP覆盖删除
EmbbedddResolverAware
@Responsity
注册DisposableBean 方便销毁
根据不同的解析器,执行parse 方法
获取setter 包装的对象
getFactoryMethodName
return getBeanFactory
可能产生新的BD
把单例对象转移到二级缓存中,因为二三级不常重复存在,会出现覆盖的问题,
bean 实例化过程
Spring当中这个是一个模板方法,具体的实现在子类
获取bean的依赖
getBean 递归去实例化依赖bean
resolveBeanClass
注册OrderedBPP
新增已执行标记
清空current集合
清除原来的BeanFactory
子类实现的一个模板方法,返回refreshBeanFactory 设置的 BeanFactory--> DefaultListableBeanFactory
doCreateBean
程序的入口
这里就是在就在Bean 进行实例化之前,完成BD的修改
postProcessBeanFactory(beanFactory)
initPropertySource
client
通过代理的方式执行controller 方法
三级缓存,就是函数式对象,需要调用getObject 才去执行创建过程
和上面的逻辑类似的,但是这个地方是注册,并不会执行任何的BPP的方法
在SpringMVC中有明确的处理
调用getBean方法拿到BDRegisterPostProcessor对象
一个模板方法
一级缓存,是完整对象
是
注册nonOrderedBPP
构建一个scaner
Beans
StandEngine
根据不同的策略实例化对象
MessageSourceAware
doRegisterBeanDefinitions
添加到registerPostProcessor去
doGetBean
注册PriorityOrderedBPP
执行普通的BFPP的postProcessBeanDefinitionRegistry
排序PriorityOrdered 集合中BFPP 并且执行PostProcessBeanFactory 方法
1.获取当前已经注册的BDRegisterPostProcessor
EnvironmentAware
设置一个while循环 把全部的BDRegisterPostProcessor 都拿出来
把listener注册到多播器中去其实就是一个listener注册过程在Springboot 中拓展,因为Springboot 有很多listener
创建并获取环境变量,验证需要的属性文件是否都已经加载进来
no不注入
是否有对于事件多播器进行设置
再说的执行BeanRegisterPostProcessor的时候可能会 新增到一些BeanFactoryPostProcessor
LifeCycle
Aware
执行Parse
addFilter
空实现来的,留给子类做扩展,初始化一些属性资源
判断是否为单例
区分出两个集合
排序MergedBDPP,并且注册到BeanFactory
合并BeanDefinition
生成一个cglib 子类
是否当前beanFactory包含messageSource
ResourceLoaderAware
AbstactXmlApplicationContext
策略模式
@Component
注册ApplicationListenerDetector
文件资源路径解析实现
在缓存中是否存在
判断自动装配的方式
这里还有很多复杂的过程、匹配具体的构造函数但是最后差不多就是这么几种方法来实例化 bean的
添加到registerPostProcessor当中去
4. getBeanNamesForType 获取到(BeanFactoryPostProcessor)
从三级中取出来,并且执行getObject 方法 来完成 对象创建
加载xml定义的BeanDefinition
ReflectionUtils.clearCache();\t\tAnnotationUtils.clearCache();\t\tResolvableType.clearCache();\t\tCachedIntrospectionResults.clearClassLoader(getClassLoader());
获取属性值 pvs
例如是SpringMVC
二级缓存,是初始化中的对象
添加到pvs 中
标记依赖关系
是否为需要检查类型
遍历beanNames
获取环境、设置BeanFactory 环境变量
可能产生新的BD定义
确认bean对象是可以进行实例化的
ThreadPool
返回一个BD
process
BPP的after 方法applyBeanPostProcessorsAfterInitialization
initLifecycleProcessor
循环执行 非排序 的BDRegisterFPP的postProcessBeanDefinitionRegistry
给BD 设置一些默认值,是否懒加载、init-Method 等
反射
调用BeanFactoryPostProcess的方法
ConfigurableApplicationContext
接口继承
setConfigLocations
resetCommonCaches
FileSystemXmlApplicationContext file: 是全局路径解析
通过对于资源路径的一系列解析操作
识别这个目标类上的其他的一些注解@Lazy,@Primary等
执行PriorityOrdered 的BDRegisterFPP的postProcessBeanDefinitionRegistry
super(...location)
applyPropertyValues通过深拷贝完成属性值的应用,确定其他的bean 也可以看见
prepareRefresh
遍历依赖的Bean对象
beforePrototypeCreation在对象创建前的工作beanName添加到prototypesCurrentlyInCreation中
然后 根据 includes 和excludes 来筛选 具体的class
设置一个setParentMessageSource
pv =getBean(propertyName)
设置循环条件为false
Supplier
原型
按类型来匹配对象
会可能添加新的BD定义
registerBeanPostProcessors(beanFactory)
如果是单例的话,删除factoryBean中的对象
FactoryMethod
InstiationAwareBeanPostProcessor
这个步骤之前都不要进去调用GetBean的方法 去拿业务的Bean因为会导致 自动装配异常
@Controller
是否包含这个属性名称对应的Bean信息
设置注册嵌入值的解析器,主要是为解析注解属性的
识别默认的一些bean
最后把BD 注册回去beanFactory
自定BeanFactory的一些其他属性,子类自己实现
MessageSource
跳过已经执行过了的
执行initialization 执行初始化
按照排序执行BFPP的postProcessBeanFactory的方法
getBean 完成之后,把对象设置进来
Import
添加已执行标记
获取它的一个注解的元数据
检查BD 是否合法,不合法直接报错
getSingleton(beanName)先去缓存当中取
判断是否需要提前曝光
其实会把beanFactory 注册到reader类当中
1.找到属性集合
Alias
Application
按照 PriorityOrdered 接口来添加到PriorityOrdered 集合,并且区分其中的MergedBDPP
清空Listeners、Event
parseCustomElement
初始化LoadTimeWeaverAware
1.对应的属性名称集合
obtainFromSupplier
InitialzingBean
MyClassPathXmlApplicationContext
一开始的BD上是没有属性相关的内容以及属性相关的注解的
registerBeanDefinitions注册BD
ComponentScanBDParse
标记pv 和bean的依赖关系
ListableBeanFactory
byName按名称
执行BPP的after方法
遍历属性集合
DefaultResourceLoader
Adapter
BeanNameAware
@Service
this.earlySingletonObjects.get(beanName)
AbstactApplicationContext
启动的完整的流程
直接执行 nonOrdered 集合中BFPP的PostProcessBeanFactory 方法
这两个注解都是依赖于BPP的
调用loadBeanDefinitions的方法加载定义的BD
parseDefaultElement
findAutowiringMetadata
设置自动装配的时候需要去忽略的一些类
排序
这里的话已经全部完成BeanDefinitionRegistry的方法postProcessBeanDefinitionRegistry
onRefresh
检查当前的BD 是否已经加载过,或者是与已经加载过的产生冲突
@Resource @AutoWired
1.刷新一个新的BeanFactory实例 DefaultListableBeanFactory2. 这一些beanFactory的相关属性,是否覆盖同名的循环依赖3.调用模板方法loadBeanDefinitions
还有一些Spring-web的实现
排序Ordered 集合中BFPP 并且执行PostProcessBeanFactory 方法
是否已存在BeanFactory
resolveBeforeInstantiation,返回一个代理对象,来使用实例化前的前置处理器
NIOEndPoint
设置容器启动的状态和关闭状态、开始时间
设置一个默认的事件多播器
finishBeanFactoryInitailization(beanFactory)
排序、然后注册到beanFactory
initMessageSource
先添加PriorityOrdered的BFPP 添加到PriorityOrdered集合
新增已执行的标记
this.singletonObjects.get(beanName);一级缓存取
设置ApplicationContextAwareProcessor
把未执行的添加进来,设置循环条件为true
标记当前的bean 在在被创建
ApplicationEvenPublisherAware
找对应的Element的解析器
添加到registerProsProcessor的集合
refreshBeanFactory
0 条评论
下一页