Spring WebMVC启动流程

一、WebMVC

web容器初始化流程
在这里插入图片描述
SpringMVC的web.xml配置


<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>

  <display-name>spring-demo</display-name>
<!--全局变量-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

<!--监听器-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

<!--乱码filter-->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern></url-pattern>
  </filter-mapping>

<!--dispatcherServlet-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
  </servlet>

  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>
<listener>标签中定义了spring容器加载器
<servlet>标签中定义了spring前端控制器

详细启动流程可参考下面链接👇
https://www.jianshu.com/p/bce0ab365535

二、servlet注册

web.xml中注册与映射配置参考第一点中内容

三、IOC容器创建

三种创建IOC容器的方式

  • ClassPathXmlApplicationContext:从项目的根目录下加载配置文件
  • FileSystemXmlApplicationContext:从磁盘中的加载配置文件
  • AnnotationConfigApplicationContext:当使用注解配置容器对象时使用此类进行注解读取,创建容器

Web中IOC容器创建
首先在web.xml中配置监听器,如第一部分所使。
接下来具体类的实现可参考下面链接👇
https://www.cnblogs.com/liuyi6/p/10317111.html
步骤总结

  • prepareRefresh 准备刷新容器

(1) initPropertySources() 自定义属性设置,空方法,留给子类继承
  
(2) getEnvironment.validateRequiredProperties 首先获取环境配置,然后校验必需属性

(3) this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); 初始化事件监听器

(4) this.earlyApplicationEvents = new LinkedHashSet<>(); 初始化早期事件

  • obtainFreshBeanFactory 获取组件工厂

(1) refreshBeanFactory 新建一个组件工厂,类型DefaultListableBeanFactory, 然后对这个组件工厂设置了一个序列化ID

(2) getBeanFactory 返回刚刚创建的组件工厂

  • prepareBeanFactory 对组件工厂做各种预处理设置

(1) 在组件工厂中设置类加载器、属性解析器等

(2) 在组件工厂中添加部分组件后置处理器,例如ApplicationContextAwareProcessor、ApplicationListenerDetector

(3) 在组件工厂中设置忽略自动注入的接口

(4) 设置自动装配规则

(5) 在组件工厂中注册一些组件,例如环境配置ConfigurableEnvironment

  • postProcessBeanFactory 组件工厂的后置处理工作
  • invokeBeanFactoryPostProcessors 执行组件工厂后置处理器

这一步是在组件工厂的标准初始化(1-4)之后进行的,主要是执行BeanFactoryPostProcessor及其子接口的

BeanFactoryPostProcessor的子接口主要是指BeanDefinitionRegistryPostProcessor,可以向容器中注册新的组件,这个接口的特点是有两个方法,一个是自身的postProcessBeanDefinitionRegistry,另一个继承自BeanFactoryPostProcessor的postProcessBeanFactory,从源码可以看出,spring会先执行BeanDefinitionRegistryPostProcessor类型的组件的自身方法,然后执行其继承方法,最后才调用非BeanDefinitionRegistryPostProcessor的BeanFactoryPostProcessor的后置处理方法

(1) 从容器器中获取BeanDefinitionRegistryPostProcessor类型的组件

(2) 将BeanDefinitionRegistryPostProcessor类型的组件按照顺序分类并排序,即是否实现了PriorityOrdered、Ordered接口

(3) 依次执行实现了PriorityOrdered接口的、实现了Ordered接口的、没有实现任何顺序接口的组件的postProcessBeanDefinitionRegistry方法

(4) 执行所有BeanDefinitionRegistryPostProcessor组件的postProcessBeanFactory方法

(5) 从容器中获取其他的BeanFactoryPostProcessor类型的组件,即不是BeanDefinitionRegistryPostProcessor类型的

(6) 剩下的步骤跟上面类似,就是先按照实现的顺序接口分类,在每个类别下排序,然后依次执行它们的postProcessBeanFactory方法

  • registerBeanPostProcessors 注册组件后置处理器,这种处理器用于拦截bean的创建过程

beanPostProcessor有很多子接口,每种子接口的执行时机各有不同

|-DestructionAwareBeanPostProcessor

|-InstantiationAwareBeanPostProcessor

|-MergedBeanDefinitionPostProcessor

|-SmartInstantiationAwareBeanPostProcessor

(1) 获取所有的beanPostProcessor的组件名

(2) 将所有的组件按优先顺序分为三类:

|-实现了PriorityOrdered接口的列表priorityOrderedPostProcessors

|-实现了Ordered接口的列表orderedPostProcessors

|-没有实现任何顺序接口的列表nonOrderedPostProcessors

还有一种特殊情况,凡是MergedBeanDefinitionPostProcessor类型的,都放在internalPostProcessors中

(3) 注册priorityOrderedPostProcessors

(4) 注册orderedPostProcessors

(5) 注册nonOrderedPostProcessors

(6) 注册internalPostProcessors

(7) 注册ApplicationListenerDetector,它的作用是在组件初始化之后判断其是否为ApplicationListner类型,如果是,则将其添加进容器的监听器集合

  • initMessageSource 初始化消息源组件,用于消息绑定、消息解析等功能,并且提供国际化解决方案

(1) 获取beanFactory

(2) 判断beanFactory中是否包含id为messageSource的组件

(3) 如果已存在,则赋值给容器的messageSource属性,这种情况是我们自己在容器中注册了这个组件

(4) 如果不存在,则新建一个DelegatingMessageSource,并赋值给容器的messageSource属性,然后在beanFactory中注册这个新组件,并设置其id为messageSource

  • initApplicationEventMulticaster 初始化事件广播器

(1) 获取beanFactory

(2) 判断beanFactory中是否存在id为applicationEventMulticaster的组件

(3) 如果已存在,则赋值给容器的applicationEventMulticaster属性,这种情况是我们自己在容器中注册了这个组件

(4) 如果不存在,则新建一个SimpleApplicationEventMulticaster,并赋值给容器的applicationEventMulticaster属性,然后在beanFactory中注册这个新组件,并设置其id为applicationEventMulticaster

  • onRefresh 没有任何操作,留给子类继承的,我们可以自定义子容器,在重写方法中做一些我们想要的操作
  • registerListeners 注册事件监听器

(1) 获取容器的属性applicationListeners,这是一个事件监听器的集合,将集合中的每个元素都添加进事件广播器

(2) 从容器中获取所有ApplicationListener类型的组件,将这些组件添加进事件广播器

(3) 发布早期事件,即容器的earlyApplicationEvents属性(参考第1(4)步),然后清空早期事件

  • finishBeanFactoryInitialization 完成剩下的单实例bean的初始化

(1) 进入DefaultListableBeanFactory.preInstantiateSingletons方法,获取容器中所有的组件id列表

(2) 遍历组件id列表,对每个组件,获取其组件定义信息,即RootBeanDefinition

(3) 从组件定义信息中筛选掉抽象类、非单实例、懒加载的,这些bean在创建容器时并不初始化,另外还有工厂组件,即实现了FactoryBean接口的,需要另外一套逻辑进行初始化

(4) 从缓存中获取单实例bean,即DefaultSingletonBeanRegistry类的singletonObjects属性,所有被创建过的单实例bean都会被缓存在这个映射中;如果缓存中存在,说明这个组件之前被创建过,直接返回

(5) 如果缓存中不存在,则开始新建

① 将组件标记为已创建,即将其id存入AbstractBeanFactory的alreadyCreated属性中

② 获取组件的定义信息,即RootBeanDefinition

③ 从定义信息中获取该组件依赖的组件,如果存在,则重新从第11(4)步开始执行,创建这些依赖的组件

④ 创建完依赖组件(如果存在)之后,以下开始正式新建目标组件

⑤ 给组件后置处理器一个机会用代理对象代替目标对象,即执行InstantiationAwareBeanPostProcessor类型的组件后置处理器的postProcessBeforeInstantiation、postProcessAfterInitialization方法

⑥ Allow post-processors to modify the merged bean definition,即执行MergedBeanDefinitionPostProcessor类型组件后置处理器的postProcessMergedBeanDefinition方法

⑦ 执行AbstractAutowireCapableBeanFactory.populateBean方法,即属性赋值在属性赋值之前,首先拿到InstantiationAwareBeanPostProcessor类型的组件后置处理器,并执行postProcessAfterInstantiation、postProcessProperties、postProcessPropertyValues方法;然后才执行该类的applyPropertyValues方法,利用反射调用组件的setter方法进行属性赋值

⑧ 执行以下三种aware接口的方法:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

⑨ 执行组件后置处理器的初始化前方法,即BeanPostProcessor.postProcessBeforeInitialization

⑩ 执行组件的初始化方法,即InitializingBean.afterPropertiesSet,以及在容器中自定义的initMethod

⑪ 执行组件后置处理器的初始化后方法,即BeanPostProcessor.postProcessAfterInitialization

⑫ 如果需要,注册组件的销毁方法,例如DisposableBean.destroy,以及在容器中自定义的destroyMethod这里只是注册,并不调用

(6) 通过第11(5)步,单实例bean已经创建并初始化完成,接着,会调用AbstractBeanFactory的父类方法—DefaultSingletonBeanRegistry.getSingleton方法,将新建的bean存入singletonObjects属性中,即缓存

(7) 回到DefaultListableBeanFactory.preInstantiateSingletons方法(见第11(1)步)如果新建的bean实现了SmartInitializingSingleton接口,则执行afterSingletonsInstantiated回调方法

  • finishRefresh 完成容器刷新

(1) 初始化生命周期处理器(LifecycleProcessor),先从BeanFactory中按类型获取, 如果没有就新建一个DefaultLifecycleProcessor,并注册进BeanFactory

(2) 获取上一步注册的生命周期处理器,回调其onRefresh方法

(3) 发布容器刷新事件,即ContextRefreshedEvent

四、bean初始化

初始化执行顺序

构造方法->Before Initialization->使用PostConstruct注解->InitializingBean接口->init-method指定的初始化方法->After Initialization
在这里插入图片描述
接下来具体类的实现可参考下面链接👇
https://www.jianshu.com/p/1a18a54c56b3

其他参考链接👇
https://www.cnblogs.com/RunForLove/p/5688731.html
https://www.jianshu.com/p/bce0ab365535
https://www.cnblogs.com/dubhlinn/p/10764845.html
https://www.jianshu.com/p/a854e23d88dd

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值