Spring listener执行过程

Spring mvc项目通过listener初始化spring IOC容器过程

方法太多太深,没法一一追到位

不空

如果在servlet中设置了配置文件的路径

如果设置了ServletContextInitParameter之globalInitializerClasses

如果设置了ServletContextInitParameter之contextInitializerClasses

如果没有对应的具体类型或者webApplicationContext没有对这个Initiallize进行继承或实现的话

条件成立

为空

非空

非空

非空

ContextLoaderListener#contextInitialized

ContextLoader#initWebApplicationContext

获取servletContext中的org.springframework.web.context.WebApplicationContext.ROOT属性

判断这个属性是否为空

抛IllegalStateException异常

记录开始时间

判断ContextLoader#contwext是否为空

为这个加载器实例化根WebApplicationContext

确定ContextClass

创建一个ConfigurableWebApplicationContext对象即web容器

通过这个工具使用无参构造器创建对象实例

判断这个容器是否为ConfigurableWebApplicationContext

设置该容器的parentContext为null

配置并刷新webApplicationContext

给这个root容器设置一个id

把servletContext配置到WebApplicationContext中

获取servlet中的contextConfigLocation参数

把该路径配置到webApplicatonContext中

getEnvironment

初始化配置信息 这个对象是standardServletEnvironment中 这个其实就是读取指定的配置文件信息

指定servletContextInitParams对应的配置文件

指定servletConfigInitParams对应的配置文件

定制容器

确定容器初始化使用的ApplicationContextInitializer列表

走进determineContextInitializerClasses这个方法

从servletContext容器中获取初始化参数#globalInitializerClasses

将该配置对应的字符串分解为独立的字符串并组成数组添加到返回值list中

从servletContext容器中获取初始化参数#contextInitializerClasses

将该配置对应的字符串分解为独立的字符串并组成数组再次添加到返回值list中

返回列表并结束determineContextInitializerClasses这个方法

遍历返回的列表分别执行以下操作

解析ApplicationContextInitialize对应的范型的具体类型

wac这里的参数是webApplicationContext

直接抛ApplicationContextException

实力化对应的initializer并加入到ContextLoader中的contextIntializers列表中

对ContextLoader中的contextInitializers进行排序

然后对这个列表中的initializer调用initialize方法进行初始化入参为webApplicationContext

定制容器方法结束

刷新容器

从这里开始进入到AbstractApplicationContext

整个refresh过程是一个代码同步块synchronized包装的

实际上就是标记一下刷新步骤

刷新容器准备阶段

设置一些状态并打印一些日志信息

web.context.support.StandardServletEnvironment#initPropertySources和前面的一样

验证必要的属性都是可解析的

判断pre-refresh applicationListeners是否为空

pre-refresh监听器为空则用AbstractApplicationContext.applicationListeners的内容覆盖

创建earlyApplicationEevents容器LinkedHashSet

AbstractApplicationContext.applicationListeners清空后用AbstratcApplicationContext.earlyApplicationListeners覆盖

prepareRefresh结束

通知子类刷新内部BeanFactory

进入到refreshBeanFactory内部看过程

刷新BeanFactory

如果已经存在的BeanFactory则清理掉

执行createBeanFactory方法

创建DefaultListableBeanFactory的对象实例并指定ParentBeanFactory

给该BeanFactory设置序列化ID

定制BeanFactory

ApplicationContext是否设置了allowBeanDefinitionOverriding属性

标记BeanFactory为可以覆盖beanDefinition

ApplicationContext是否设置了allowCircularReferences属性

标记BeanFactory为可以循环刷新

org.springframework.context.support.AbstractRefreshableApplicationContext#loadBeanDefinitions 有多种实现#PropertiesbeanDefinitionReader XmlBeanDefinitionReader 有待研究实现细节

将这个BeanFactory赋值给AbstractRefreshApplicationContext的beanFactory属性

返回容器中的beanFactory

配置这个beanFactory的信息

设置SpEl表达式解析器

添加属性解析器它的作用就是解析各种配置信息到需要的地方

添加Bean初始化的后置处理器之ApplicationListenerDetector

忽略EnvironmentAware的实现 避免使用set进行依赖注入

忽略EmbeddedValueResolverAware的实现 避免使用set进行依赖注入

忽略ResourceLoaderAware的实现 避免使用set进行依赖注入

忽略ApplicationEventPublisherAware的实现 避免使用set进行依赖注入

忽略MessageSourceAware的实现 避免使用set进行依赖注入

忽略ApplicationContextAware的实现 避免使用set进行依赖注入

忽略ApplicationStartupAware的实现 避免使用set进行依赖注入

解决自动注入将容器中的beanFactory注入到BeanFactory的实现类

解决自动注入将容器注入到ResourceLoader实现类

解决自动注入将容器注入到ApplicationEventPublisher的实现类

解决自动注入将容器注入到ApplicationContext的实现类

检测是否设置了org.graalvm.nativeimage.imagecode这个技术很牛逼但是不了解

向容器中添加environment对象

向容器中添加systemProperties对象

向容器中添加systemEnvironment对象

向容器中添加applicationStartup对象

prepareBeanFactory结束

执行钩子方法对前面的步骤进行补充可以继续添加对象到容器或添加后置处理器

打印日志'spring.context.beans.post-process'

执行BeanFactory的后置处理器 这个方法很重待深入研究

注册Bean的后置处理

初始化容器的initMessageSource国际化处理

初始化容器的initApplicationEventMulticaster事件广播

容器的钩子方法

容器注册监听器和earlyApplicatonEvents关联

完成BeanFactory初始化

设置setConversionService转换服务

如果没有BeanFactoryPostProcessor设置一个嵌入式的解析器

创建LoadTimeWeaverAware实例

停止使用临时的classLoader进行加载

冻结beanFactory中对应的bean的原数据禁止修改

实例化剩余的对象实例 lazy的除外

finishBeanFactoryInitialization结束

完成刷新

清理资源缓存

初始化生命周期处理器 待研究

创建bean加入treeMap

广播一个ContextRefreshedEvent事件

将liveBean托管给MBeanServer

最后层层返回将这个webApplicationContext注册到servletContext中

posted @   Eular  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示