SSM-SpringMVC-SpringMVC初始化-初始化映射请求上下文

本文详细介绍了SpringMVC中DispatcherServlet如何初始化请求上下文,包括何时初始化、DispatcherServlet的设计原理以及核心组件如文件解析器、国际化解析器、主题解析器等的初始化过程。DispatcherServlet在服务器启动时或首次请求时初始化SpringIOC容器,并根据配置文件初始化相关策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SSM-SpringMVC-SpringMVC初始化-初始化映射请求上下文

​ 映射请求上下文是通过DispatcherServlet初始化的,根据自己的需要配置启动时初始化,或者等待用户第一次请求时进行初始化。在WEB工程中没有注册ContextLoaderListener,这时DispatcherServle就会在其初始化对SpringIOC进行初始化


选择什么时候初始化:

​ 大部分情况下,让DispatcherServle在服务器启动期间就完成SpringIoc容器初始化,可以在WEB容器刚开始就对其初始化,在整个WEB的初始化中,不只是DispatcherServle需要得到SpringIOC资源,其他组件也需要,因此大部分情况下都建议使用ContextLoaderListener进行初始化


DispatcherServle设计:

在这里插入图片描述

是一个可以加载加载WEB容器中的Servlet


​ web容器对于servlet的初始化,首先调用其init初始化方法,对于DispactherServlet也是如此,该方法位于父类HttpServletBean

public final void init() throws ServletException {
    PropertyValues pvs = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig(), this.requiredProperties);
    if (!pvs.isEmpty()) {
        //根据参数初始化 bean 的属性
        try {
            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);
        } catch (BeansException var4) {
            if (this.logger.isErrorEnabled()) {
                this.logger.error("Failed to set bean properties on servlet '" + this.getServletName() + "'", var4);
            }

            throw var4;
        }
    }
	//交由子类去实现
    this.initServletBean();
}

上面代码中,可以看到initServletBean方法,在FrameworkServlet类中也能看见该方法,所以它覆盖了FrameworkServlet类中的initServletBean方法。


FrameworkServlet中的initServletBean方法

protected final void initServletBean() throws ServletException {
    this.getServletContext().log("Initializing Spring " + this.getClass().getSimpleName() + " '" + this.getServletName() + "'");
    if (this.logger.isInfoEnabled()) {
        this.logger.info("Initializing Servlet '" + this.getServletName() + "'");
    }

    long startTime = System.currentTimeMillis();

    try {
        //初始化SpringIOC容器
        this.webApplicationContext = this.initWebApplicationContext();
        this.initFrameworkServlet();
    } catch (RuntimeException | ServletException var4) {
        this.logger.error("Context initialization failed", var4);
        throw var4;
    }

    if (this.logger.isDebugEnabled()) {
        String value = this.enableLoggingRequestDetails ? "shown which may lead to unsafe logging of potentially sensitive data" : "masked to prevent unsafe logging of potentially sensitive data";
        this.logger.debug("enableLoggingRequestDetails='" + this.enableLoggingRequestDetails + "': request parameters and headers will be " + value);
    }

    if (this.logger.isInfoEnabled()) {
        this.logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms");
    }

}

方法initWebApplicationContext:

protected WebApplicationContext initWebApplicationContext() {
    WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
    WebApplicationContext wac = null;
    //判断是否已经被初始化
    if (this.webApplicationContext != null) {
        //如果webIOC容器已经在启动的时候创建,那么久沿用它
        wac = this.webApplicationContext;
        if (wac instanceof ConfigurableWebApplicationContext) {
            ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)wac;
            if (!cwac.isActive()) {
                //如果SPirng IOC容器还没有刷新,那么就进行刷新父类容器上下文,设置id等操作
                //处理父容器为空的情况
                if (cwac.getParent() == null) {
                    cwac.setParent(rootContext);
                }

                this.configureAndRefreshWebApplicationContext(cwac);
            }
        }
    }
	
    //没有被初始化,则查找是否存在的Spring Web IoC容器
    if (wac == null) {
        wac = this.findWebApplicationContext();
    }
    
    //没有初始化,也没有找到存在的Spring Web Ioc容器,则DispatcherServlet自己创建
    if (wac == null) {
        wac = this.createWebApplicationContext(rootContext);
    }

    //当onRefresh方法没有被调用过,执行onRefresh方法
    if (!this.refreshEventReceived) {
        synchronized(this.onRefreshMonitor) {
            this.onRefresh(wac);
        }
    }

    if (this.publishContext) {
        //作为Servlet的上下文属性发布IOC容器
        String attrName = this.getServletContextAttributeName();
        this.getServletContext().setAttribute(attrName, wac);
    }

    return wac;
}

​ 当IOC容器没有对应初始化,DispatcherServlet会尝试去初始化它,最后调度onRefresh方法,是DispatcherServlet十分关注的方法,该方法就在DispatcherServlet中


onRefresh方法在DispatcherServlet代码中如下:

protected void onRefresh(ApplicationContext context) {
    this.initStrategies(context);
}

其中调用了自身的initStrategies方法:

protected void initStrategies(ApplicationContext context) {
    //初始化文件的解析
    this.initMultipartResolver(context);
    //本地解析化
    this.initLocaleResolver(context);
    //主题解析
    this.initThemeResolver(context);
    //处理器解析
    this.initHandlerMappings(context);
    //处理器的适配器
    this.initHandlerAdapters(context);
    //Handler的异常处理解析器
    this.initHandlerExceptionResolvers(context);
    //当处理器没有返回逻辑视图名等相关信息时,自动将请求 URL 映射为逻辑视图名
    this.initRequestToViewNameTranslator(context);
    //视图逻辑名称转化器,即允许返回逻辑视图名称,然后它会找到真实的视图
    this.initViewResolvers(context);
    //这是一个关注Falsh开发的Map管理器
    this.initFlashMapManager(context);
}
  • MultipartResolver:文件解析器,用于支持服务器的文件上传
  • LocaleResolver:国际化解析器,可以提供国际化的功能
  • ThemeResolver:主题解析器,类似软件皮肤的转换功能
  • HandlerMapping:会 包装用户提供一个控制器的方法和对它的一些拦截,通过调用他就能运行控制器
  • handlerAdapter:处理适配器,因为处理器会在不同的上下文运行,SpringMVC会先找到合适的适配器,然后运行处理器服务方法
  • HandlerExceptionResolver:处理器异常解析器,当产生异常,可以通过异常解析器来处理
  • RequestTo ViewNameTranslator :视图逻辑名称转换器,在控制前中返回一个视图的名称,通过它可以找到实际的视图,当处理器没有返回逻辑视图名等相关信息时,自动将请求URL映射为逻辑视图名
  • ViewResolver:视图解析器,当控制器返回后,通过视图解析器会把逻辑视图名称进行解析,然后定位实际视图

器来处理

  • RequestTo ViewNameTranslator :视图逻辑名称转换器,在控制前中返回一个视图的名称,通过它可以找到实际的视图,当处理器没有返回逻辑视图名等相关信息时,自动将请求URL映射为逻辑视图名
  • ViewResolver:视图解析器,当控制器返回后,通过视图解析器会把逻辑视图名称进行解析,然后定位实际视图

​ 上面是Spring MVC主要的组件的初始化,实际,这些组件DispatcherServlet会根据配置文件DispatcherServlet.properties进行初始化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值