SpringMVC理解之一:应用上下文webApplicationContext

来源:互联网 发布:ne555数据手册 编辑:程序博客网 时间:2024/06/05 08:00
  • 一、先说ServletContext

      javaee标准规定了,servlet容器需要在应用项目启动时,给应用项目初始化一个ServletContext作为公共环境容器存放公共信息。ServletContext中的信息都是由容器提供的。

    举例:

    通过自定义contextListener获取web.xml中配置的参数 1.容器启动时,找到配置文件中的context-param作为键值对放到ServletContext中 2.然后找到listener,容器调用它的contextInitialized(ServletContextEvent event)方法,执行其中的操作 例如:在web.xml中配置
    view sourceprint?
    1.<context-param>
    2.   <param-name>key</param-name>
    3.   <param-value>value123</param-value>
    4.</context-param>
    5.<listener>
    6.   <listener-class>com.brolanda.contextlistener.listener.ContextListenerTest</listener-class>
    7.</listener>
    配置好之后,在该类中获取对应的参数信息
    view sourceprint?
    01.packagecom.brolanda.contextlistener.listener;
    02. 
    03.importjavax.servlet.ServletContext;
    04.importjavax.servlet.ServletContextEvent;
    05.importjavax.servlet.ServletContextListener;
    06. 
    07.publicclassContextListenerTestimplementsServletContextListener {
    08.     
    09.    publicvoidcontextDestroyed(ServletContextEvent event) {
    10.        System.out.println('*************destroy ContextListener*************');
    11.    }
    12.     
    13.    @SuppressWarnings('unused')
    14.    publicvoidcontextInitialized(ServletContextEvent event) {
    15.        System.out.println('*************init ContextListener*************');
    16.        ServletContext servletContext = event.getServletContext();
    17.        System.out.println('key:'+servletContext.getInitParameter('key'));
    18.    }
    19.     
    20.}

    执行流程:

      web.xml在<context-param></context-param>标签中声明应用范围内的初始化参数

    1.启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: <listener></listener> 和 <context-param></context-param> 
  • 2.紧接着,容器创建一个ServletContext(上下文)。在该应用内全局共享。
  • 3.容器将<context-param></context-param>转化为键值对,并交给ServletContext.

    4.容器创建<listener></listener>中的类实例,即创建监听.该监听器必须实现自ServletContextListener接口

    5.在监听中会有contextInitialized(ServletContextEvent event)初始化方法

                  在这个方法中获得ServletContext = ServletContextEvent.getServletContext();
                “context-param的值” = ServletContext.getInitParameter('context-param的键'); 
  • 6.得到这个context-param的值之后,你就可以做一些操作了.注意,这个时候你的WEB项目还没有完全启动完成.这个动作会比所有的Servlet都要早.换句话说,这个时候,你对<context-param>中的键值做的操作,将在你的WEB项目完全启动之前被执行.     
  • web.xml中可以定义两种参数:     
  • 一个是全局参数(ServletContext),通过<context-param></context-param> 。
  • 一个是servlet参数,通过在servlet中声明 <init-param><param-name>param1</param-name> <param-value>avalible in servlet init()</param-value> </init-param>       
  • 第一种参数在servlet里面可以通过getServletContext().getInitParameter('context/param')得到。第二种参数只能在servlet的init()方法中通过this.getInitParameter('param1')取得  

    二、spring上下文容器配置

      spring为我们提供了实现ServletContextListener接口的上下文初始化监听器:org.springframework.web.context.ContextLoaderListener

      spring为我们提供的IOC容器,需要我们指定容器的配置文件,然后由该监听器初始化并创建该容器。要求你指定配置文件的地址及文件名称,一定要使用:contextConfigLocation作为参数名称 如下所示:

    <context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/classes/spring-context*.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>

    该监听器,默认读取/WEB-INF/下的applicationContext.xml文件。但是通过context-param指定配置文件路径后,便会去你指定的路径下读取对应的配置文件,并进行初始化。

    三、spring上下文容器配置后,初始化了什么?

      既然,ServletContext是由Servlet容器初始化的,那spring的ContextLoaderListener又做了什么初始化呢?

         1、servlet容器启动,为应用创建一个“全局上下文环境”:ServletContext         
  • 2、容器调用web.xml中配置的contextLoaderListener,初始化WebApplicationContext上下文环境(即IOC容器),加载context-param指定的配置文件信息到IOC容器中。WebApplicationContext在ServletContext中以键值对的形式保存         
  • 3、容器初始化web.xml中配置的servlet (springMvc项目中的SpringMvcServlet),为其初始化自己的上下文信息servletContext,并加载其设置的配置信息到该上下文中。将WebApplicationContext设置为它的父容器。         
  • 4、此后的所有servlet的初始化都按照3步中方式创建,初始化自己的上下文环境,将WebApplicationContext设置为自己的父上下文环境。          对于作用范围而言,在DispatcherServlet中可以引用由ContextLoaderListener所创建的ApplicationContext中的内容,而反过来不行。当Spring在执行ApplicationContext的getBean时,如果在自己context中找不到对应的bean,则会在父ApplicationContext中去找。这也解释了为什么我们可以在DispatcherServlet中获取到由ContextLoaderListener对应的ApplicationContext中的bean。

     四、spring配置时:<context:exclude-filter>的使用原因即为什么在applicationContext.xml中排除controller,而在spring-mvc.xml中incloud这个controller

        既然知道了spring的启动流程,那么web容器初始化webApplicationContext时作为公共的上下文环境,只需要将service、dao等的配置信息在这里加载,而servlet自己的上下文环境信息不需要加载。故,在applicationContext.xml中将@Controller注释的组件排除在外,而在dispatcherServlet加载的配置文件中将@Controller注释的组件加载进来,方便dispatcherServlet进行控制和查找。故,配置如下:   
  • applicationContext.mxl中: 
  • <!-- 使用Annotation自动注册Bean:在主容器中不扫描@Controller注解,在SpringMvc子容器中只扫描@Controller注解。 --><context:component-scan base-package="com.zsq.cn"><!-- base-package如果多个,用“,”分隔 --><context:exclude-filter type="annotation"expression="org.springframework.stereotype.Controller" /></context:component-scan>
  • spring-mvc.xml中:
  • <!-- 使用Annotation自动注册Bean,只扫描@Controller --><context:component-scan base-package="com.zsq.cn" use-default-filters="false"><!-- base-package 如果多个,用“,”分隔  这里一定要设置use-default-filters="false" 不让容器去自动扫描@Component,@Service等注解--><context:include-filter type="annotation"expression="org.springframework.stereotype.Controller" /></context:component-scan>


  • 原文链接

  • 阅读全文
    0 0
    原创粉丝点击