spring容器启动流程
2023-08-05 15:03:59 0 举报
学习笔记
作者其他创作
大纲/内容
如果想在用户自定义对象中获取容器对象呢?
invokeBeanFactoryPostProcessors
是否有自定义destroy方法
markBeanAsCreated(beanName)标记A对象正在被创建
31
首先将所有的特殊的静态的监听器注册上
循环完毕之后,将deepCopy中的对象A添加掉B对象的属性中
initApplicationEventMulticaster
设置bean工厂序列化ID;定制化bean工厂,设置属性,包括设置同名称不同定义的对象和是否允许循环依赖
校验被标识为required的配置是否为null,如果是则抛出MissingRequiredPropertiesException
设置bean工厂后置处理器
beanDefinitionbean定义信息
prepareRefresh()
AbstractApplicationContext.refresh()
继承
⑥/20
处理器Handler
正是在创建两个相互依赖的对象的过程中形成了作图所示的一个闭环,所以造成了循环依赖的问题。那么,是不是只要我们将这个闭环断开就可以解决循环依赖的问题呢其实,熟悉对象的创建过程就会知道,在创建B对象的过程中,对B对象中的a属性赋值的时候,容器中其实已经存在了A对象的,只是它不是我们正常使用的一个完整的对象,而是一个半成品。所以此时缓存的作用就体现出来了。大致思路是,当我们创建任何一个对象的时候,在这个对象被实例化出来之后,初始化动作之前,则将这个半成品对象放在一个缓存中,然后当其他的对象在创建的过程中,如果需要此对象,可以将此半成品对象拿来使用(当然,如果已经有成品对象,优先使用成品对象)
SimpleControllerHandlerAdapter
三级缓存singletonFactories
getBean
是否初次刷新
BeanNameUrlHandlerMapping
填充属性(set方法)
关闭先前的bean工厂(如果有),并为上下文下一个生命周期初始化一个bean工厂
bean实例化
进入方法
进入registerBeanPostProcessors
④
33
给对象赋值的方式有两种:
实例化B对象属性a=null
填充B对象中的a属性
设置上下文状态,将开启态设置为true,关闭态设置为false
注册监听器,并播出容器早期事件
实例化A对象此时属性b=null
1.用户请求
34
RequestMappingHandlerAdapter
+ supportsInternal(HandlerMethod handlerMethod)
初始化占位符属性资源。默认不作任何操作
⑩/24
此时就需要使用到aware方法,比如在一个User类中注入beanFactory和applicationContext时,可以实现BeanFactoryAware和ApplicationContextAware两个接口,此时容器就会自动帮我们注入这两个属性。详情请阅读源码。注意,aware分两步处理。
例如AOP
beanPostProcessor接口的实现类AbstractAutoProxyCreator有个createProxy方法
筛选出分别实现了PriorityOrdered接口,Ordered接口,MergedBeanDefinitionPostProcessor接口,和其他普通的后处理器
有
直接赋值
实现
populateBean
springMVC处理器适配器类继承关系图
初始化
37
obtainFreshBeanFactory()目的是获得刷新的beanFactory创建DefaultLIstableBeanFactory
AbstractHandlerAdapter
首先计算出目标bean后处理器的个数,并检查
依次按照顺序注册这些后处理器,最后注册内部后处理器
HandlerFunctionAdapter
before
具体步骤
执行三级缓存中的lambda表达式生成singletonObject 对象
after
前端控制器DispatcherServlet
构造器方式
抽象类
当前A对象是否正在创建中
RequestMappingHandlerMapping
+ isHandler(Class<?> beanType)
new反射
这是一个抽象方法。在对bean工厂进行标准的初始化之后,在应用上下文内部修改bean工厂。所有的bean都已加载,但是未实例化。所以这里可以实现注册一些特殊的后置处理器
RouterFunctionMapping
+ getHandlerInternal
postProcessBeanFactory
最后处理其他的BeanFactoryPostProcessor
36
doCreateBean
bean的生命周期
prepareBeanFactory
32、a 对象正在创建中
AbstractDetectingUrlHandlerMapping
bean
set
HttpRequestHandlerAdapter
beanFactoryPostProcessor
beanFactory
38、后退
9.返回view对象
8.请求解析视图
createBean(\"a\")doCreateBean(\"a\")
cglib
是GenericApplicationContext
注解
1、例如准备beanPostProcessor2、准备监听器、事件、广播器
SimpleServletHandlerAdapter
4.请求执行Handler
准备bean工厂
收集处理其他BeanDefinitionRegistrypostProcessor
finishRefresh
getSingleton(\"a\")
是否实现InitializingBean接口
Spring MVC 找 Controller 流程:1、扫描整个项目(spring已经做了)定义一个 Map 集合2、拿到所有加了 @Controller 注解的类3、遍历类里面的所有方法对象4、判断 方法是否添加@RequestMapping注解5、把@RequestMapping注解的 value 作为 map 的 key 存入,把method对象作为value 存入map集合6、根据用户发送的请求,拿到请求中的URI7、使用请求呃URI作为map的key去map里面get看是否有返回值
类
生成mapper的动态代理
17
beanFactory.preInstantiateSingletons()
完成此上下文的 bean 工厂的初始化,初始化所有剩余的单例 bean
getSingleton(\"a\")从一级缓存取出来为null
实例化剩下的所有单例
对上面的beanFactory进行属性值的设置工作
获取当前环境
⑤/19 否
首先调用bean工厂后置处理器,方法:PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()
设置bean工厂ID,并返回当前bean工厂
BeanDefinitionReader接口
B对象已经初始化完成,放入一级缓存
初始化一个初期应用程序监听器放在集合
开始finishBeanFactoryInitialization
创建B对象
AbstractUrlHandlerMapping
+ getHandlerInternal
onRefresh
singletonFactory.getObject()执行上面传来的lambda表达式
循环
beanPostProcessor
将ApplicationListenerDetector作为最后注册的后处理器用以处理代理
beanFactory反射:Constructor ctor = Clazz.getDeclareConstructor();Object obj = ctor.newInstance();
getSingleton(\"a\")从一和二级缓存取出来为null
无
XML
35、返回
SimpleUrlHandlerMapping
createBeanInstance
创建容器
可以覆盖的模板方法以添加特定于上下文的刷新工作。 在单例实例化之前调用特殊 bean 的初始化。默认没有任何操作
然后将其他的监听器bean添加进去。注意,此时还不能实例化FactoryBeans
将生成的对象放入二级缓存,并删除三级缓存,再返回此对象
3.返回处理器执行链
AbstractHandlerMethodMapping<T>
+ abstract getHandlerInternal
忽略一些自动装配的接口;注册一些默认的环境的bean
this.beanFactory.getBean(resolvedName)
再收集处理实现了Ordered的接口的BeanFactoryPostProcessor
然后再收集处理实现了PriorityOrdered接口的BeanFactoryPostProcessor
properties
registerBeanPostProcessors
18
视图解析器ViewResolver
处理器适配器HandlerAdapter
容器对象
10.渲染
通过三级缓存方式解决循环依赖
doGetBean
初始化 ApplicationEventMulticaster。 如果上下文中没有定义,则使用 SimpleApplicationEventMulticaster
容器中查找A对象
用户自定义对象
从methodCache中找方法
HandlerAdapter
实例化之前有一些准备工作
填充A对象的b属性
接口
2.请求查询Handler
registerListeners
12/26、开始填充A对象的属性
③
createBean
初始化事件广播器
⑦/21
首先实例化ConversionService,如果有
Container
⑧/22
再收集并处理实现了Ordered接口的BeanDefinitionRegistrypostProcessor
三级缓存中分别保存的是什么对象?第一级:成品对象第二级:半成品对象第三级:lambda表达式只有两级缓存行不行?理论上是可行的,但是当类有生成代理对象时就不行
11/25
PostProcessor
init()方法
多个后置处理器循环调用而非 链式调用。具体 请看PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()方法
finishBeanFactoryInitialization
一级缓存singletonObjects
7.返回ModelAndView
首先收集并处理实现了PriorityOrdered接口的BeanDefinitionRegistrypostProcessor
无法解决循环依赖的问题
13/27
完整对象
等同于容器
查询
spring容器中按照使用者分为两类
getSingleton(\"b\")
16/30
注册必要的Destruction相关回调接口
RequestMappingInfoHandlerMapping
既然已经有多播器了,就传播一个容器早期事件
处理器映射器HandlerMapping
HandlerMapping
+ getHandler(params)+ usesPathPatterns
这里做一点说明,BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的触发类型基本相同。都是在BeanDefinition加载之后,Bean实例化之前。但是也有不同,根据代码注释(文档)对其的接口定义是不同的。BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry是在所有的bean definition 加载完毕之后,然后还可以继续向注册表中添加bean definition;而BeanFactoryPostProcessor#postProcessBeanFactory是在所有bean definition 加载完毕之后,然后还可以对这些bean的属性做修改或者添加的动作。
退出方法
user
14/28
beanFactorPostProcessor
视图Jsp/freemaker
yaml...
⑨/23
从容器中查找B对象
调用aware方法
getBean(\"a\")doGetBean
创建A对象
AbstractHandlerMapping
+ getHandler(params)+ abstract getHandlerInternal
15/29、进入
二级缓存earlySingletonObjects
例如,springboot其实就是实现后置处理器完成自动装配的,具体阅读:ConfigurationClassPostProcessor
JDK
否AbstractRefreshableApplicationContext
①
11.响应用户
spring循环依赖,三级缓存
将对象深度拷贝 并放入deepCpoy数组中
循环依赖的形成原因
WelcomePageHandlerMapping
0 条评论
回复 删除
下一页