• Spring笔记-springmvc源码阅读


    【本文图部分取自别处】

    一、Jsp与Servlet

    1.JSP九大内置对象

    2.生命周期

    3.Servlet生命周期

    init( ),service( ),destroy( )是Servlet生命周期的方法。代表了Servlet从“出生”到“工作”再到“死亡 ”的过程。Servlet容器(例如TomCat)会根据下面的规则来调用这三个方法:
    1).init( ),当Servlet第一次被请求时,Servlet容器就会开始调用这个方法来初始化一个Servlet对象出来,但是这个方法在后续请求中不会在被Servlet容器调用,就像人只能“出生”一次一样。我们可以利用init( )方法来执行相应的初始化工作。调用这个方法时,Servlet容器会传入一个ServletConfig对象进来从而对Servlet对象进行初始化。
    2).service( )方法,每当请求Servlet时,Servlet容器就会调用这个方法。就像人一样,需要不停的接受老板的指令并且“工作”。第一次请求时,Servlet容器会先调用init( )方法初始化一个Servlet对象出来,然后会调用它的service( )方法进行工作,但在后续的请求中,Servlet容器只会调用service方法了。
    3).destory,当要销毁Servlet时,Servlet容器就会调用这个方法,就如人一样,到时期了就得死亡。在卸载应用程序或者关闭Servlet容器时,就会发生这种情况,一般在这个方法中会写一些清除代码。

    4..Servlet处理流程

    二、SpringMVC

    1.SpringMVC处理时序图

    3.SpringMVC处理流程图

    DispatcherServlet

    4.详解dispatcherServlet

    类图

    执行流程图

    代码解读

    HttpServletBean
    初始化 :主要是通过当前的servlet类型实例转换为BeanWrapper类型实例,以便使用Spring提供的注入功能进行对应属性的注入。
    1.封装初始化参数
    2.将servlet实例转为BeanWrapper实例
    3.注册相对于Resource的属性编辑器
    如果有Resource类型的属性,就会使用ResouceEditor去解析。
    4.属性注入
    BeanWrapper自动注入属性。
    5.servletBean的初始化
    该过程由子类完成。在FrameworkServlet中覆盖了HttpServletBean中的initServletBean方法
    init()
    //从web.xml获取contextConfigLocation属性配置
    PropertyValues pvs = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties);
    if (!pvs.isEmpty()) {
    //将当前的Servlet类转为Spring可操作的Wrapper类
    BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
    //服务器信息
    ResourceLoader resourceLoader = new ServletContextResourceLoader(this.getServletContext());
    bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.getEnvironment()));
    //该处理为空实现,留给子类,使用模板方法
    this.initBeanWrapper(bw);
    //属性的注入
    bw.setPropertyValues(pvs, true);
    }
    //模板方法,子类初始化的入口方法,留给子类扩展
    this.initServletBean();

    FrameworkServlet:
    servletBean的初始化:关键是initWebApplicationContext()方法。
    1.获取spring根容器rootContext
    2.设置webApplicationContext,并根据情况调用onRefresh()
    a) webApplicationContext的寻找及创建包含以下几个步骤:
    (1)通过构造函数的注入进行初始化。
    当进入initWebApplicationContext方法后通过判断this.webApplicationContext != null 后,
    便可以确定this.webApplicationContext是否是通过构造函数来初始化的。由于DispatcherServlet只可被声明一次,而this.webApplicationContext除了initWebApplicationContext()方法可以创建外,还可以通过构造函数来初始化。
    (2)通过contextAttribute进行初始化
    (3) 重新创建WebApplicationContext 实例
    通过以上方法都没有拿到实例,则只能重新创建新的实例。
    b) onRefresh():
    无论是通过构造方法注入还是通过单独创建,都免不了会调用configureAndRefreshWebApplicationContext方法来对已经创建的WebApplicationContext实例进行刷新。
    onRefresh是FrameworkServlet类中提供一个模版方法,在其子类DispatcherServlet中对它进行了重写,用于刷新Spring在Web功能实现中所必须使用的全局变量。
    3.将webApplicationContext设置到ServletContext中
    initServletBean()
    //初始化webApplicationContext
    this.webApplicationContext = this.initWebApplicationContext();
    //获取spring的根容器rootContext
    WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
    WebApplicationContext wac = null;
    if (this.webApplicationContext != null) {
    //上下文实例在构造函数中被注入
    wac = this.webApplicationContext;
    if (wac instanceof ConfigurableWebApplicationContext) {
    ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)wac;
    if (!cwac.isActive()) {
    if (cwac.getParent() == null) {
    cwac.setParent(rootContext);
    }
    //刷新上下文环境
    this.configureAndRefreshWebApplicationContext(cwac);
    }
    }
    }
    if (wac == null) {
    //已经存在servletContext时,获取contextAttribute
    wac = this.findWebApplicationContext();
    }
    if (wac == null) {
    //创建一个webApplicationContext
    wac = this.createWebApplicationContext(rootContext);
    }
    if (!this.refreshEventReceived) {
    this.onRefresh(wac);
    }
    if (this.publishContext) {
    String attrName = this.getServletContextAttributeName();
    this.getServletContext().setAttribute(attrName, wac);
    }
    //模板方法
    this.initFrameworkServlet();

    DispatcherServlet.class
    1.初始化
    (1)MultipartResolver:用于处理文件上传
    (2)LocaleResolver:在Spring中配置国际化配置
    (3)初始化ThemeResolver:在Web中通过主题Theme来控制网页风格
    onRefresh(ApplicationContext context)
    this.initStrategies(context)
    this.initMultipartResolver(context);
    this.initLocaleResolver(context);
    this.initThemeResolver(context);
    this.initHandlerMappings(context);
    this.initHandlerAdapters(context);
    this.initHandlerExceptionResolvers(context);
    this.initRequestToViewNameTranslator(context);
    this.initViewResolvers(context);
    this.initFlashMapManager(context);
    doService(request, response)
    doDispatch(request, response)
    //通过HandlerMapping获取HandlerExecutionChain: 包括handler和List<HandlerInterceptor>
    HandlerExecutionChain mappedHandler = this.getHandler(processedRequest);
    HandlerMapping hm = this.handlerMappings.iterator().next();
    //BeanNameUrlHandlerMapping
    //SimpleUrlHandlerMapping
    //RequestMappingHandlerMapping
    HandlerExecutionChain handler = hm.getHandler(request);
    //通过handler获取适配器HandlerAdapter
    HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());

    //执行HandlerInterceptor.preHandle
    mappedHandler.applyPreHandle(processedRequest, response);//处理HandlerInterceptor
    interceptor.preHandle(request, response, this.handler);
    //通过HandlerAdapter调用具体handler的handle
    ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    //1.SimpleControllerHandlerAdapter.handle()
    ((Controller)handler).handleRequest(request, response);
    //2.HttpRequestHandlerAdapter
    ((HttpRequestHandler)handler).handleRequest(request, response);
    //3.SimpleServletHandlerAdapter
    ((Servlet)handler).service(request, response);
    //4.RequestMappingHandlerAdapter
    //执行HandlerInterceptor.postHandle
    mappedHandler.applyPostHandle(processedRequest, response, mv);
    interceptor.postHandle(request, response, this.handler, mv);
    //通过ViewResolver获取view
    this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
    //如果有异常
    this.processHandlerException(request, response, handler, exception);
    HandlerExceptionResolver handlerExceptionResolver = this.handlerExceptionResolvers.iterator().next();
    ModelAndView exMv = handlerExceptionResolver.resolveException(request, response, handler, ex);
    //无异常
    this.render(mv, request, response);
    ViewResolver viewResolver = this.viewResolvers.iterator().next();
    View view = viewResolver.resolveViewName(viewName, locale);

    重要组件

     2.SpringMVC体系结构

    handlerMapping  url与控制器handler的映射

    handlerAdapter  控制器适配器

    viewResolver  视图仓库

    view  视图

    handlerExceptionResolver  异常捕捉

    HandlerInterceptor  拦截器

    5.SpringMVC体系结构 uml

    三、手写Springmvc

    (1)MvcBeanFactory

    (2)模拟请求

  • 相关阅读:
    安全参考和书安 NPM、PYPI、DockerHub 备份
    [NTT][组合]P4491 [HAOI2018]染色
    [主席树][哈希][最短路]CF464E The Classic Problem
    序章在那星雨之夜
    [二分][后缀数组]luogu P2463 [SDOI2008]Sandy的卡片
    GDOI 2021 退役记
    [后缀数组][单调栈]luogu P4248 [AHOI2013]差异
    [BFS]luogu P2536 [AHOI2005]病毒检测
    [多项式下降幂][组合][二项式定理]luogu P6620 [省选联考 2020 A 卷] 组合数问题
    AtCoder Regular Contest 116 总结
  • 原文地址:https://www.cnblogs.com/hongyedeboke/p/12749768.html
Copyright © 2020-2023  润新知