zoukankan      html  css  js  c++  java
  • web.xml中的ContextLoaderListener和DispatcherServlet区别

    ContextLoaderListener和DispatcherServlet都会在Web容器启动的时候加载一下bean配置. 区别在于:

      DispatcherServlet一般会加载MVC相关的bean配置管理(如: ViewResolver, Controller, MultipartResolver, ExceptionHandler, etc.)

      ContextLoaderListener一般会加载整个Spring容器相关的bean配置管理(如: Log, Service, Dao, PropertiesLoader, DataSource Bean, etc.)

    ContextLoaderListener继承ContextLoader类,实现ServletContextListener接口(该接口监听servlet容器的启动和销毁),ContextLoaderListener重写了监听容器启动和销毁的方法,在启动时(contextInitialized),会调用initWebApplicationContext方法,进行web容器初始化。

    	/**
    	 * Initialize the root web application context.
    	 */
    	@Override
    	public void contextInitialized(ServletContextEvent event) {
    		initWebApplicationContext(event.getServletContext());
    	}
    
    
    	/**
    	 * Close the root web application context.
    	 */
    	@Override
    	public void contextDestroyed(ServletContextEvent event) {
    		closeWebApplicationContext(event.getServletContext());
    		ContextCleanupListener.cleanupAttributes(event.getServletContext());
    	}
    

    在initWebApplicationContext方法时父类contextloader内的方法(精简):

    在方法内回调用createWebApplicationContext()创建容器,该容器回根据spring内部的配置文件创建,最后强制为ConfigurableWebApplicationContext对象

    	public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
    		if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
    			throw new IllegalStateException(
    					"Cannot initialize context because there is already a root application context present - " +
    					"check whether you have multiple ContextLoader* definitions in your web.xml!");
    		}
    		try {
    			// Store context in local instance variable, to guarantee that
    			// it is available on ServletContext shutdown.
    			if (this.context == null) {
    				this.context = createWebApplicationContext(servletContext);//ConfigurableWebApplicationContext类型对象
    			}
    			if (this.context instanceof ConfigurableWebApplicationContext) {//进行初始化操作
    				ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
    				if (!cwac.isActive()) {
    					// The context has not yet been refreshed -> provide services such as
    					// setting the parent context, setting the application context id, etc
    					if (cwac.getParent() == null) {
    						// The context instance was injected without an explicit parent ->
    						// determine parent for root web application context, if any.
    						ApplicationContext parent = loadParentContext(servletContext);
    						cwac.setParent(parent);
    					}
    					configureAndRefreshWebApplicationContext(cwac, servletContext);//真正初始化,在该方法内部有refresh()方法,在方法回调用ConfigurableWebApplicationContext父类的refresh()方法进行容器初始化
                                                                //也就是AbstractApplicationContext类中的refresh()方法 } } servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); return this.context; } }
        protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
            Class<?> contextClass = determineContextClass(sc);
            if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
                throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
                        "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
            }
            return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
        }
        protected Class<?> determineContextClass(ServletContext servletContext) {
            String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
            if (contextClassName != null) {
                try {
                    return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
                }
                catch (ClassNotFoundException ex) {
                    throw new ApplicationContextException(
                            "Failed to load custom context class [" + contextClassName + "]", ex);
                }
            }
            else {
                contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
                try {//通过反射得到一个class对象
                    return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());
                }
                catch (ClassNotFoundException ex) {
                    throw new ApplicationContextException(
                            "Failed to load default context class [" + contextClassName + "]", ex);
                }
            }
        }

     DispatcherServlet本质是一个servlet,能够拦截请求

    servlet会有初始化init,同dispatcherservlet,会进行一些初始化操作:

        protected void initStrategies(ApplicationContext context) {

          //初始化多部请求解析器,没有默认的实现
          initMultipartResolver(context); //文件上传
          //初始化地域解析器,默认实现是AcceptHeaderLocaleResolver
          initLocaleResolver(context);
          //初始化主题解析器,默认实现是FixedThemeResolver
          initThemeResolver(context);
          //初始化处理器映射,这是个集合, 默认实现是BeanNameUrlHandlerMapping和DefaultAnnotationHandlerMapping
          initHandlerMappings(context);
          //初始化处理器适配器,这是个集合,默认实现是HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter和AnnotationMethodHandlerAdapter
          initHandlerAdapters(context);
          //初始化处理器异常解析器,这是个集合,默认实现是AnnotationMethodHandlerExceptionResolver,ResponseStatusExceptionResolver和DefaultHandlerExceptionResolver
          initHandlerExceptionResolvers(context);
          //初始化请求到视图名解析器,默认实现是DefaultRequestToViewNameTranslator
          initRequestToViewNameTranslator(context);
          //初始化视图解析器,这是个集合,默认实现是InternalResourceViewResolver
          initViewResolvers(context);   

    }

  • 相关阅读:
    mysql学习笔记-数据库相关操作
    bugku-flag在index里(本地文件包含漏洞+php伪协议的结合应用)
    nmap的指令学习
    雅礼2018-03-11
    两道题,雅礼一题矩阵转置
    2018-03-05 计算鞍点
    多维数组
    TCP拥塞控制
    TCP三次握手和四次挥手
    MySQL事务隔离级别详解
  • 原文地址:https://www.cnblogs.com/nxzblogs/p/9139687.html
Copyright © 2011-2022 走看看