SpringMVC处理流程
-
进入统一入口:Dispatchersevlet
-
创建:由spring创建
-
初始化:在第一次接收请求时初始化,初始化MVC九大组件,比较重要的有:
- HandlerMapping:根据路径匹配处理器方法,记录映射
- HandlerAdaptor:处理器适配器,执行处理器方法
- HandlerExceptionResolver:异常处理器
- ViewResolver:视图解析器
-
RequestMappingHandlerMapping匹配对应的处理器方法,将方法封装为handlerMethod,与对应的拦截器结合在一起称为调用链返回给Dispatchersevlet
-
调用拦截器preHandle()
-
RequestMappingHandlerAdaptor执行handle方法,将得到的handlerMethod完善为servletInvocableHandlerMrthod,执行过程为:
- @ModelAttribute增强:补充模型参数。
- @InitBinder增强:补充自定义类型转换
-
HandlerMethodArgumentReslover—参数解析器准备参数
- @RequestBody增强
-
调用servletInvocableHanlderMethod
-
HandlerMethodReturnValueResolver—返回值解析器处理返回值,返回值类型为ModelAndView:
- @ResponseBody增强
- 如果为null,不进行视图解析与渲染
- 如果不为空,进行视图解析与渲染
- @ResponseBody增强
-
调用拦截器postHandle()
-
如果3-5步骤有异常,则通过ExceptionHandlerExceptionResolver进行异常处理;
- 进行@ExceptionHandler增强
- 如果没有异常,则进行视图解析与渲染
-
调用拦截器的afterCompletion()
【注】:由@ControllerAdvice实现增强效果
SpringBoot启动流程
第一阶段:SpringApplication构造过程:
- 记录BeanDefinition源
- 推断应用程序类型—deduceFromClassPath()判断类路径下是否存在某个类。(非web,基于servlet、基于reactive)
- 记录ApplicationContext初始化器—对ApplicationContext进行扩展。
- 记录监听器—ApplicationListener
- 推断启动类—deduceMainApplicationClass()推断main方法所在的类。
第二阶段:执行run()方法:
-
得到事件发布器—SpringApplicationRunListeners;在特定的时间发布事件
- 发布starting事件
-
封装启动args参数,执行runner使用
-
执行prepareEnvironment()方法
-
在Environment中添加命令行参数,Environment的PropertySource中默认有1.系统属性、2.系统环境变量;
这一步就是在Propertysource中添加命令行源。
-
添加ConfigurationPropertySource,用它的attach()方法加入到PropertySource中,处理参数名的格式。
- 发布environmentPrepared事件
-
发布事件后,由监听器—EnvironmentPostProcesserApplicationListener监听,对Environment的PropertySource进行增强即添加新的源。
- 例如Application.proerties
-
使用Binder根据Environment中Spring.main开头的键值数据绑定到SpringApplication对象中。
-
-
打印banner
-
根据推断的应用程序类型创建容器。
-
执行preparedContext()方法:
- 准备容器,在这里会调用ApplicationContextInitializer—初始化器进行扩展。
- 发布ContextPrepared事件
- 加载BeanDefinition:
- 首先执行getAllSource()方法,得到所有的BeanDefinition源
- 其次执行load()方法进行加载
- 发布ContextLoaded事件
- 准备容器,在这里会调用ApplicationContextInitializer—初始化器进行扩展。
-
执行refreshContext()方法:
- 调用ApplicationContext.refresh方法,完成初始化。
- 发布started事件
- 调用ApplicationContext.refresh方法,完成初始化。
-
执行callRunner()方法:
- 执行runner,由具体业务决定做什么
- ApplicationRunner 封装args
- CommandLineRunner 直接使用args
- 发布running事件
- 执行runner,由具体业务决定做什么