web.xml是所有web项目的根源,没有它,任何web项目都启动不了,所以有必要了解相关的配置.

 

ContextLoderListener,ContextLoaderServlet,DispatcherServlet 区别

本段引用自 : http://blog.csdn.net/feiyu8607/article/details/6532397

web.xml中可以有三种方式来配置xml去加载Bean:

org.springframework.web.context.ContextLoaderListener
org.springframework.web.context.ContextLoaderServlet
org.springframework.web.servlet.DispatcherServlet

  1. ContextLoaderListener 和 ContextLoaderServlet : 本质上是等同的,都是调用ContextLoader来加载web程序的上下文,加载完成以后,都是在ServletContext中,只不过listener需要Servlet2.3及以上支持。
  2. ContextLoaderListene与DispatcherServlet : 用DispatcherServlet载入的Bean是隶属于此Servlet的(所以spring可以配置多个分别拥有各自环境的DispatcherServlet),因此其他servlet无法获取到该Context。这一现象在buffalo配置时曾经出现(无法找到服务bean)。分析了buffalo和spring的源码后,将xml在ContextLoaderListener配置才得以解决。   所以web.xml文件中若只使用了一个dispatcherservlet来进行分发,则使用dispatcherservlet contextloaderlistener 来加载bean实例是等效的。

 各元素初始化过程

本段引用自: http://blog.csdn.net/fupengyao/article/details/50605954

初始化过程:

  1. 在启动Web项目时,容器(比如Tomcat)会读web.xml配置文件中的两个节点<listener>和<contex-param>。
  2. 接着容器会创建一个ServletContext(上下文),应用范围内即整个WEB项目都能使用这个上下文。
  3. 接着容器会将读取到<context-param>转化为键值对,并交给ServletContext。
  4. 容器创建<listener></listener>中的类实例,即创建监听(备注:listener定义的类可以是自定义的类但必须需要继承ServletContextListener)。
  5. 在监听的类中会有一个contextInitialized(ServletContextEvent event)初始化方法,在这个方法中可以通过event.getServletContext().getInitParameter("contextConfigLocation") 来得到context-param 设定的值。在这个类中还必须有一个contextDestroyed(ServletContextEvent event) 销毁方法.用于关闭应用前释放资源,比如说数据库连接的关闭。
  6. 得到这个context-param的值之后,你就可以做一些操作了.注意,这个时候你的WEB项目还没有完全启动完成.这个动作会比所有的Servlet都要早。

所以 web.xml的加载过程是context-param >> listener  >> fileter  >> servlet

 

 

context-param和init-param区别

web.xml里面可以定义两种参数:
(1)application范围内的参数,存放在servletcontext中,可以在servlet中通过getServletContext().getInitParameter("fruitName");

在web.xml中配置如下:

<context-param>  
           <param-name>fruitName</param-name>  
           <param-value>orange</param-value>  
</context-param>

(2)servlet范围内的参数,只能在servlet的init()方法中通过this.getInitParameter("fruitName")取得.

在web.xml中配置如下:

<servlet>  
    <servlet-name>PersonServlet</servlet-name>  
    <servlet-class>com.king.servlet.PersonServlet</servlet-class>  
    <init-param>  
       <param-name>fruitName</param-name>  
       <param-value>watermelon</param-value>  
    </init-param>  
    <load-on-startup>0</load-on-startup>  
</servlet>  

load-on-startup说明:

  1. load-on-startup 元素标记容器是否应该在web应用程序启动的时候就加载这个servlet,(实例化并调用其init()方法)。
  2. 它的值必须是一个整数,表示servlet被加载的先后顺序。
  3. 如果该元素的值为负数或者没有设置,则容器会当Servlet被请求时再加载。
  4. 如果值为正整数或者0时,表示容器在应用启动时就加载并初始化这个servlet,值越小,servlet的优先级越高,就越先被加载。值相同时,容器就会自己选择顺序来加载。

 

 

ContextLoderListener配置

  1. <param-name>contextConfigLocation</param-name>为固定写法.
  2. <param-value></param-value>中可以通过classpath或/WEB-INF 两种路径来加载xml文件.
<!-- application范围内的参数,存放在ServletContext中 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
              <!--加入Spring总体配置文件-->
            classpath:config/applicationContext.xml
            <!-- /WEB-INF/classes/applicationContext.xml,/WEB-INF/classes/spring-srevlet.xml -->
        </param-value>
    </context-param>

    <!-- Spring监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

 

filter配置

说明都在注释中

<!--  配置Spring框架自身的拦截器 解决乱码问题  --> 
     <filter>
        <filter-name>SpringCharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter> 
    
    <filter-mapping>
        <filter-name>SpringCharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

 

 

servlet配置

说明都在注释中

    <servlet>
        <!-- DispatcherServlet会默认加载WEB-INF/[DispatcherServlet的Servlet名字]-servlet.xml配置文件 -->
        <servlet-name>springServlet</servlet-name>
        <!-- 把所有请求交给Spring Web MVC框架处理 -->
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <!-- 下面的配置最好直接在一行,且不要有空格,如果输成 "classpath:空格config/applicationContext.xml"  By朱青 -->
            <!-- 将会报错:org.xml.sax.SAXParseException: Content is not allowed in prolog.  -->
            <param-value>classpath:config/spring/springMVC.xml</param-value>
        </init-param>
         <load-on-startup>1</load-on-startup> 
        <!-- 1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。
        2)它的值必须是一个整数,表示servlet应该被载入的顺序
        2)当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;
        3)当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。
        4)正数的值越小,该servlet的优先级越高,应用启动时就越先加载。
        5)当值相同时,容器就会自己选择顺序来加载。 -->
    </servlet>
    <servlet-mapping>
        <servlet-name>springServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

 

注解,定时任务等xml配置在哪加载合适?

如果您把上面的段落都仔细阅读完了,会发现<servlet>配置如果<load-on-startup>没有手动配置,那么默认是servlet第一次被访问到才会去初始化的,如果该servlet等web应用启动后,过了很久都没有被访问,那么注释和定时任务都是不会启动的.

而且我们应当小心listener和servlet重复加载注解引起的启动时间浪费  及  重复加载定时任务引起的数据冲突或不一致.

所以注解,定时任务都建议放在全局监听的<context-param>中,而不建议放在<servlet>的<init-param>中.

 

 

BeanFactory获取

在EE web应用的servlet或controller中,可通过WebApplicationContextUtils来获取BeanFactory

BeanFactory factory = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
UserManager userManager = (UserManager)factory.getBean("userManager");

在SE 标准应用中可直接通过java代码来获取BeanFactory

BeanFactory factory = new ClassPathXmlApplictionContext("applicationContext.xml");

 

真实环境web.xml,applicationContext.xml,springMVC.xml

web.xml

<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" >


    <display-name>SpringMVC</display-name>
    
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <error-page>
        <error-code>500</error-code>
<!-- <exception-type>java.lang.NullPointerException</exception-type> -->   <!-- 还有一种配置是指定异常跳转 -->
        <location>/WEB-INF/jsp/common/errorPage.jsp</location>
    </error-page>

    <!-- 基础总配置文件位置 -->
    <!-- application范围内的参数,存放在ServletContext中 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
              <!--加入Spring总体配置文件-->
            classpath:config/applicationContext.xml
            <!-- /WEB-INF/classes/applicationContext.xml,/WEB-INF/classes/spring-srevlet.xml -->
        </param-value>
    </context-param>

    <!-- Spring监听器 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    <!-- log4j configuration load -->
     <servlet> 
        <servlet-name>log4jInit</servlet-name> 
        <servlet-class>config.log.Log4jInit</servlet-class> 
        <init-param> 
            <param-name>log4j-config-file</param-name> 
            <param-value>/WEB-INF/classes/config/log/log4j.properties</param-value> 
        </init-param> 
        <load-on-startup>1</load-on-startup> 
    </servlet> 
    
    
        <!--  配置Spring框架自身的拦截器 解决乱码问题  --> 
     <filter>
        <filter-name>SpringCharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter> 
    
    <filter-mapping>
        <filter-name>SpringCharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    <servlet>
        <!-- DispatcherServlet会默认加载WEB-INF/[DispatcherServlet的Servlet名字]-servlet.xml配置文件 -->
        <servlet-name>springServlet</servlet-name>
        <!-- 把所有请求交给Spring Web MVC框架处理 -->
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <!-- 下面的配置最好直接在一行,且不要有空格,如果输成 "classpath:空格config/applicationContext.xml"  By朱青 -->
            <!-- 将会报错:org.xml.sax.SAXParseException: Content is not allowed in prolog.  -->
            <param-value>classpath:config/spring/springMVC.xml</param-value>
        </init-param>
         <load-on-startup>1</load-on-startup> 
        <!-- 1)load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法)。
        2)它的值必须是一个整数,表示servlet应该被载入的顺序
        2)当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet;
        3)当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载。
        4)正数的值越小,该servlet的优先级越高,应用启动时就越先加载。
        5)当值相同时,容器就会自己选择顺序来加载。 -->
    </servlet>
    <servlet-mapping>
        <servlet-name>springServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    
    <!-- session超时 -->
    <session-config>
        <session-timeout>60</session-timeout>
    </session-config>
</web-app>
View Code

相关文章: