• ContextLoaderListener可以不写嘛?


    写了那么久的Spring,经常写这样的配置,这就是几行Spring、SpringMvc的基本配置, 但是最近也看到不写最前面的context-param以及listener的,好奇记录下.

    <context-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>classpath:spring.xml</param-value>
    </context-param>
    
    <listener>
    		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <servlet>
    	<servlet-name>Springmvc</servlet-name>
    	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    	<load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
    	<servlet-name>Springmvc</servlet-name>
    	<url-pattern>/</url-pattern>
    </servlet-mapping>

    ContextLoaderListener监听器介绍

    image

    上图是ContextLoaderListener的结构图以及javadoc.    ContextLoaderListener肯定要实现ServletContextListener,这点不用多说,另外继承的类是ContextLoader.

    JavaDoc告诉我们很多信息:Bootstrap listener启动类监听器用来启动/停止Spring Web上下文容器,代理给ContextLoader来完成启动启动工作。 listener应当在Log4jConfigListener之后注册。

               Spring3.1支持通过ContextLoaderListener构造器方式注入Web 上下文容器,servlet3.0也支持使用WebApplicationInitializer启动Spring容器来替代web.xml写法。

    主要关注的是ContextLoaderListener,先主要关注容器启动这块吧!监听器的contextInitialized 方法:调用了ContextLoader的initWebApplicationContext,还是代理给了ContextLoader完成容器启动工作。

    代码太占篇幅了,记录下加载过程即可:

       step1.检查ServletContext上下文是否有WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE这个属性,没有是正常的,有的话就说明Spring根容器重复定义了!

       step2. 尝试读取context-param中为contextClass的值作为根容器的class属性,如果没有指定context-param属性,就以ContextLoader类所在同一路径下的ContextLoader.properties文件中的 org.springframework.web.context.WebApplicationContext 作为key取出value , 默认为 org.springframework.web.context.support.XmlWebApplicationContext , 以这个作为Spring根容器类型,并且实例化XmlWebApplicationContext;

       step3. Spring根容器的ServletContext设置为当前ServletContext,并且读取web.xml中 其contextConfigLocation作为 Spring配置文件位置,最后调用 根容器的refresh 方法完成容器启动!

       step4. 根容器启动完之后,设置到 ServletContext的WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 属性中 ,并且存到了ContextLoader中,可以通过静态方法ContextLoader.getCurrentWebApplicationContext就能获取到 Spring根容器。

    DispatcherServlet的初始化

    初始化的入口位于 org.springframework.web.servlet.HttpServletBean#init :

      SpringMvc容器类型默认为XmlWebApplicationContext,反射实例化该对象,并且通过ServletContext的 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE属性得到Spring根容器,

    作为SpringMVC容器的父容器。  另外,像如下形式的SpringMvc,没有指定spring配置文件的位置,那默认加载的配置文件位置为: /WEB-INF/Springmvc-servlet.xml 

    <servlet>
           <servlet-name>Springmvc</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    
    	<servlet-mapping>
    		<servlet-name>Springmvc</servlet-name>
    		<url-pattern>/</url-pattern>
    </servlet-mapping>

    也就是说没有ContextLoaderListener,对于SpringMvc容器的影响就是没了父容器,照样可以使用SpringMVC的特性

    获取Spring根容器以及Web容器的方式

    提供五种获取Spring根容器方案、三种获取Spring父容器方案:

    @Controller
    @RequestMapping("/context")
    public class ContextController implements ApplicationContextAware {
    
        @Autowired
        private ApplicationContext ac;
    
        @RequestMapping("/demo1")
        @ResponseBody
        public String demo1(HttpServletRequest request){
            System.out.println("Spring根容器方式一:"+request.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE));
            System.out.println("Spring根容器方式二:"+ContextLoader.getCurrentWebApplicationContext());
            System.out.println("Spring根容器方式三:"+ WebApplicationContextUtils.getRequiredWebApplicationContext(request.getServletContext()));
            System.out.println("Spring根容器方式四:"+ WebApplicationContextUtils.getWebApplicationContext(request.getServletContext()));
            System.out.println("Spring根容器方式五:"+ac.getParent());
            System.out.println("SpringMvc容器获取方式一:"+ac);
            System.out.println("SpringMvc容器获取方式二:"+ac2);
                              //SpringMvc容器获取方式三 继承抽象类 WebApplicationObjectSupport,方式二方式三不能同时用
                              //调用getApplicationContext
            return "hello World";
        }
    
        private ApplicationContext ac2;
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            ac2=applicationContext;
        }
    }
  • 相关阅读:
    Android 11 的5个新安全和隐私功能,不更新会面临被黑客入侵风险
    SSL / TLS新加密漏洞,黑客是这样读取敏感数据,看看修复方法!
    蓝牙新漏洞,黑客可以轻松控制你的手机,全球数亿台设备受影响
    Visa信用卡漏洞,新的PIN验证黑客可绕过,并进行非接触式付款
    思科是如何遭黑客入侵?原因:XSS缺陷到RCE缺陷
    WhatsApp现神秘漏洞,黑客可远程查看聊天记录
    郭盛华:免受网络黑客攻击的5个技巧
    Apache服务器现3个致命漏洞,黑客可远程监听
    centos 下安装python3 的MySQLdb
    MySQL创建用户与授权及删除
  • 原文地址:https://www.cnblogs.com/lvbinbin2yujie/p/10616889.html
Copyright © 2020-2023  润新知