当前位置: 首页 > news >正文

SpringMVC启动流程

SpringMVC启动流程

文章目录

  • SpringMVC启动流程
      • 1.启动前的相关配置
      • 2.启动流程
        • 1.启动tomcat容器
        • 2.创建spring容器
        • 3.创建springmvc容器

1.启动前的相关配置

  1. spring容器相关配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="com.anyi"></context:component-scan><bean id="user" class="com.anyi.beans.User"><property name="username" value="anyi"></property><property name="password" value="123"></property></bean>
</beans>
  1. springmvc容器相关配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"></beans>
  1. web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"version="4.0"><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring-config.xml</param-value></context-param><servlet><servlet-name>mvc-test</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>mvc-test</servlet-name><url-pattern>/</url-pattern></servlet-mapping><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
</web-app>

2.启动流程

1.启动tomcat容器

使用idea会自动启动tomcat容器,调用spring容器的初始化方法

2.创建spring容器
  1. 在初始化tomcat容器之前,必须先启动tomcat容器,启动之后tomcat会调用初始化方法initWebApplicationContext()来对容器进行初始化
@Override
public void contextInitialized(ServletContextEvent event) {// 初始化web容器,先开始初始化的spring容器initWebApplicationContext(event.getServletContext());
}
  1. 在这里会调用configureAndRefreshWebApplicationContext() 方法来进行spring容器的初始化
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {// 设置一个容器idif (ObjectUtils.identityToString(wac).equals(wac.getId())) {// The application context id is still set to its original default value// -> assign a more useful id based on available informationString idParam = sc.getInitParameter(CONTEXT_ID_PARAM);if (idParam != null) {wac.setId(idParam);}else {// Generate default id...wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +ObjectUtils.getDisplayString(sc.getContextPath()));}}// 设置servlet上下文wac.setServletContext(sc);String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);if (configLocationParam != null) {// 设置spring配置文件路径wac.setConfigLocation(configLocationParam);}// The wac environment's #initPropertySources will be called in any case when the context// is refreshed; do it eagerly here to ensure servlet property sources are in place for// use in any post-processing or initialization that occurs below prior to #refresh// 设置一些环境对象ConfigurableEnvironment env = wac.getEnvironment();if (env instanceof ConfigurableWebEnvironment) {((ConfigurableWebEnvironment) env).initPropertySources(sc, null);}// 可以定制化contextcustomizeContext(sc, wac);// 调用刷新方法wac.refresh();
}
  1. 刷新完成后,就完成了spring容器的初始化
3.创建springmvc容器

上述完成了tomcat、spring容器的创建和启动,接下来就是springmvc容器的启动了,而springmvc中最重要的就是Servlet,而Servlet的生命周期包含三个init、service、destroy。

  1. init方法调用是在DispatcherServlet的父类HttpServletBean中调用init()方法
@Override
public final void init() throws ServletException {// 调用初始化springmvc容器// Set bean properties from init parameters.// 从web.xml中获取servlet的配置文件PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);if (!pvs.isEmpty()) {try {BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));initBeanWrapper(bw);bw.setPropertyValues(pvs, true);}catch (BeansException ex) {if (logger.isErrorEnabled()) {logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);}throw ex;}}// 初始化ServletBean// Let subclasses do whatever initialization they like.initServletBean();
}
  1. 在initServletBean方法中会调用initWebApplicationContext()来进行springmvc容器的初始化
protected WebApplicationContext initWebApplicationContext() {// 获取父容器WebApplicationContext rootContext =WebApplicationContextUtils.getWebApplicationContext(getServletContext());WebApplicationContext wac = null;...// 进行容器刷新configureAndRefreshWebApplicationContext(cwac);// 判断是否有事件发布if (!this.refreshEventReceived) {// Either the context is not a ConfigurableApplicationContext with refresh// support or the context injected at construction time had already been// refreshed -> trigger initial onRefresh manually here.synchronized (this.onRefreshMonitor) {onRefresh(wac);}}...return wac;
}
  1. 调用configureAndRefreshWebApplicationContext()方法来刷新容器
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {// id 验证...// 设置一些属性值wac.setServletContext(getServletContext());wac.setServletConfig(getServletConfig());wac.setNamespace(getNamespace());// 放入一个ContextRefreshListener监听器wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));// The wac environment's #initPropertySources will be called in any case when the context// is refreshed; do it eagerly here to ensure servlet property sources are in place for// use in any post-processing or initialization that occurs below prior to #refreshConfigurableEnvironment env = wac.getEnvironment();if (env instanceof ConfigurableWebEnvironment) {((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());}// 可以进行拓展修改postProcessWebApplicationContext(wac);// 设置一些初始化器applyInitializers(wac);// 开始容器刷新wac.refresh();
}
  1. 调用AbstractApplicationContext类中的refresh()方法来创建BeanFactory等容器刷新工作,详细见spring篇
  2. 在完成刷新后回到用一个方法finishRefresh()
protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).// 清理缓存clearResourceCaches();// Initialize lifecycle processor for this context.// 实例化生命周期处理器initLifecycleProcessor();// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();// Publish the final event.// 发布事件publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this);
}
  1. 这里会调用publishEvent()方法,由多播器来广播发布一个容器已经完成刷新的事件,会调用具体的监听器来进行处理。
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {...// Multicast right now if possible - or lazily once the multicaster is initializedif (this.earlyApplicationEvents != null) {this.earlyApplicationEvents.add(applicationEvent);}else {// 调用多播器广播事件,让监听器来处理getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);}...
}
  1. 遍历所有的监听器,最终会由我们前面注册的一个ContextRefreshListener监听器来进行处理,最终会调用他的onApplicationEvent方法
public void onApplicationEvent(ContextRefreshedEvent event) {this.refreshEventReceived = true;synchronized (this.onRefreshMonitor) {onRefresh(event.getApplicationContext());}
}
  1. 调用DispatcherServlet类中onRefresh(event.getApplicationContext())方法来完成springmvc九大模块的实例化
    1. 初始化 MultipartResolver:主要用来处理文件上传
    2. 初始化 LocaleResolver:主要用来处理国际化配置,基于URL参数的配置(AcceptHeaderLocaleResolver)
    3. 初始化 ThemeResolver:主要用来设置主题
    4. 初始化 HandlerMappings:映射器,用来完成request和controller的对应
    5. 初始化 HandlerAdapters:处理适配器,主要包含Http请求处理适配器,简单控制处理适配器,注解方法处理适配器
    6. 初始化 HandlerExceptionResolvers:基于HandlerExceptionResolver接口的异常处理
    7. 初始化RequestToViewNameTranslator:当controller处理器方法没有返回一个View对象或者逻辑视图名称,并且方法中没有直接往response的输入流中写入数据的时候
    8. 初始化 ViewResolvers:将ModelAndView选择合适的视图进行渲染处理器
    9. 初始化 FlashMapManager:提供请求存储属性,可供其他请求使用
@Override
protected void onRefresh(ApplicationContext context) {initStrategies(context);
}/*** Initialize the strategy objects that this servlet uses.* <p>May be overridden in subclasses in order to initialize further strategy objects.*/
protected void initStrategies(ApplicationContext context) {// 初始化 MultipartResolver:主要用来处理文件上传initMultipartResolver(context);// 初始化 LocaleResolver:主要用来处理国际化配置,基于URL参数的配置(AcceptHeaderLocaleResolver)initLocaleResolver(context);// 初始化 ThemeResolver:主要用来设置主题initThemeResolver(context);// 初始化 HandlerMappings:映射器,用来完成request和controller的对应initHandlerMappings(context);// 初始化 HandlerAdapters:处理适配器,主要包含Http请求处理适配器,简单控制处理适配器,注解方法处理适配器initHandlerAdapters(context);// 初始化 HandlerExceptionResolvers:基于HandlerExceptionResolver接口的异常处理initHandlerExceptionResolvers(context);// 初始化RequestToViewNameTranslator:当controller处理器方法没有返回一个View对象或者逻辑视图名称,并且方法中没有直接往response的输入流中写入数据的时候initRequestToViewNameTranslator(context);// 初始化 ViewResolvers:将ModelAndView选择合适的视图进行渲染处理器initViewResolvers(context);// 初始化 FlashMapManager:提供请求存储属性,可供其他请求使用initFlashMapManager:(context);
}
  1. 至此完成springmvc的所有启动流程,可以等待请求进入了。
http://www.dtcms.com/a/461227.html

相关文章:

  • HTTP 请求方法与参数上传形式的关系
  • 如何减少 Elasticsearch 集群中的分片数量
  • 当通过API发送请求的方式自动触发Jenkins job报错HTTP Status 403 – Forbidden的解决办法
  • 一个网站如何工作流程建立网站需要哪些手续
  • H3C网络设备 实验二:搭建两个局域网,使两个局域网相互通信(路由器,固定ip)
  • 临平房产做网站的公司wordpress屏蔽功能org
  • Skywalking 的本地开发配置
  • iOS 上架 App 全流程实战,应用打包、ipa 上传、App Store 审核与工具组合最佳实践
  • JavaScript核心构成与基础语法详解2
  • 邹平网站建设公司淘宝网站开始怎么做
  • fs 文件系统:Node.js 操作磁盘的 “万能工具”
  • Android + iOS 手机抓包 App 实操教程
  • 智慧新零售时代:施易德系统平衡技术与人力,赋能门店运营
  • 标准编码与算法
  • Python获取变量名本身​​——varname库
  • 专业站全返利网站建设
  • 网站设计提案安阳市建设工程领域网站
  • 鸿蒙(OpenHarmony)声明式 UI 开发入门:从「智慧校园」项目学基础语法
  • js移动开发框架
  • 【腾讯拥抱开源】Youtu-Embedding:基于CoDiEmb的一个协作而独特的框架,用于信息检索与语义文本相似性中的统一表征学习
  • 西蔵自治区建设厅网站wordpress防盗链插件
  • VSCode中使用conda activate 虚拟环境,没报错,但没进入环境
  • vue修改element-ui的默认的class
  • ModuleNotFoundError: No module named ‘UI_xiangmu‘
  • 网站建设方案及报价霍州做网站
  • mybatis-generator插件自动生成mapper及其实体模型配置
  • 计算机毕业设计 基于k-means的校园美食推荐系统 Python 大数据毕业设计 Hadoop毕业设计选题【附源码+文档报告+安装调试】
  • 【代码大模型-后门安全】Backdoors in Neural Models of Source Code
  • javaweb后端优雅处理枚举
  • 帝国cms小程序搞起来简直好用的不行