spring web.xml 難點配置總結【轉】

web.xml

web.xml是全部web項目的根源,沒有它,任何web項目都啓動不了,因此有必要了解相關的配置.html

 

ContextLoderListener,ContextLoaderServlet,DispatcherServlet 區別

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

web.xml中能夠有三種方式來配置xml去加載Bean:mysql

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

  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/50605954spring

初始化過程:sql

  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");express

在web.xml中配置以下:apache

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

(2)servlet範圍內的參數,只能在servlet的init()方法中經過this.getInitParameter("fruitName")取得.spring-mvc

在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>  

 

 

 

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" id="WebApp_ID" version="2.5">


    <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

 

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:util="http://www.springframework.org/schema/util" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"
                           >
    
    
    <!-- 啓動spring註解,當自動掃描啓動後,該配置能夠去掉 -->
    <context:annotation-config />
    
    <!-- 自動掃描 --> 
    <context:component-scan base-package="com.bobo.code" />
    
    <!-- 6. 不一樣環境之間切換配置文件,能夠讀取該配置文件的${test.jdbc.username}表明key去取value ,
            [1]. 在Spring的Bean定義中使用
            [2]. 也可用於Spring在java代碼中的註解
    -->
<!--     <context:property-placeholder location="classpath:/config/database/mysql_jdbc.properties" />  -->
    <context:property-placeholder location="classpath:/config/database/oracle_jdbc_virtual_tele.properties" /> 
    
    <!--DataBase Configuration -->
    <!-- Spring的事務管理器有5個,都實現了PlatformTransactionManager接口 
        DataSourceTransactionManager                 JDBC事務管理器 
        HibernateTransactionManager                    Hibernate事務管理器 
        JdoTransactionManager                               JDO事務管理器 
        JtaTransactionManager                           JTA事務管理器      
        PersistenceBrokerTransactionManager    Apache的OJB事務管理器 -->
    <!-- <bean id="dataSource"    class="org.springframework.jdbc.datasource.DriverManagerDataSource"> -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${dataSource.driverClassName}" />
        <property name="url" value="${dataSource.url}" />
        <property name="username" value="${dataSource.username}" />
        <property name="password" value="${dataSource.password}" />
    </bean> 

    <!-- 7. 配置myBatis客戶端 -->
     <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">  
          <property name="configLocation">
            <value>classpath:config/mybatis/sqlmap-config.xml</value>
        </property>  
        <property name="dataSource" ref="dataSource" />  
    </bean>

    
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    
    
    <!-- 表示事務的開始策略。
        propagation="REQUIRED"  表示name的那個方法必需要在一個事務的環境中運行。
        read-only="true"  表示只讀事務,就是不涉及到數據的修改,只是查詢,這是對事務的優化。
     -->
    <!-- 配置事務的傳播特性 -->
    <!-- 8. 配置事務的傳播特性     -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>

  
  
    <!-- 10. 配置哪些類哪些方法使用事務<aop:pointcut id="allManagerMethod" expression="execution(* com.test.server.dao.*.impl.*(..))"/> -->
    <aop:config>
        <aop:pointcut                  id="allManagerMethod"     expression="execution(* com.bobo.code.service.impl.*.*(..))" />
        <aop:advisor  pointcut-ref="allManagerMethod" advice-ref = "txAdvice"/>
    </aop:config>


    












    
    <!-- 
    <import resource="classpath*:config/spring/dataSource.xml"/>
    <import resource="classpath*:config/spring/spring-bean.xml"/> -->
    <import resource="classpath*:config/spring/timetrigger.xml"/>
</beans>
View Code

 

springMVC.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:util="http://www.springframework.org/schema/util"  
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:mvc="http://www.springframework.org/schema/mvc"  
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
       http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <!-- MVC -->

    <!--  經過Web.xml的DispatcherServlet加載 -->
    
    <!-- 會自動註冊DefaultAnnotationHandlerMapping與AnnotationMethodHandlerAdapter 兩個bean,是spring MVC爲@Controllers分發請求所必須的 -->
    <!-- <mvc:annotation-driven /> --> 
    
    <!-- 2. 組件掃描路徑配置,讓Spring 容器知道須要掃描哪些包路徑下能夠加載到容器中的類 -->
    <!--     多個掃描路徑配置  base-package="com.app,com.core,JUnit4" 也能夠寫多份,通常直接寫多份 -->
    <context:component-scan base-package="com.bobo.code" />

     <!-- 啓動spring事務註解, $該啓用必須在springMVC中,而不能在applicationContext.xml中配置,否則事務註解無效$
         也就是說只有這一行才能真正開啓事務,單獨地在類或方法上註解@Transaction只是做了事務標記而以-->  
     <tx:annotation-driven  transaction-manager="transactionManager" />
    <!-- 3. 處理在類級別上的@RequestMapping註解 -->
    
    <bean    class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="interceptors">
            <list>
                <!-- 多個攔截器,順序執行 -->
                <!-- <ref bean="SpringMVCInterceptor" /> -->
                <!-- <ref bean="OpenSessionInViewInterceptor" /> -->
            </list>
        </property>
    </bean>
    
    <!-- 4.處理方法級別上的@RequestMapping註解 -->
    <bean 
            class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="webBindingInitializer">
            <bean
                class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
                <property name="conversionService">
                    <bean
                        class="org.springframework.format.support.FormattingConversionServiceFactoryBean"></bean>
                </property>
            </bean>
        </property>
    </bean>

    <!-- 5.對模型視圖名稱的解析,即給模型視圖名稱添加先後綴 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/" /> <!-- 讓ModelAndView("jsp/teacher/listTeachers.jsp") 從/WEB-INF/目錄下開始 -->
        <property name="suffix" value="" />
        <!-- <property name="suffix" value=".jsp" /> -->
        <!-- Spring內部資源解析類 -->
        <property name="viewClass"    value="org.springframework.web.servlet.view.InternalResourceView" />
    </bean>
    
    <!-- 6.異常解析器 -->  
  <bean id="simpleMappingExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">  
    <property name="exceptionMappings">  
      <props>  
        <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">jsp/common/exception</prop>  
      </props>  
    </property>  
  </bean>  
    
</beans>
View Code

 

 

遺留問題(目前未知緣由)

個人一個spring 遠程方法調用的 測試項目中,xml配置文件只能放在servlet中去訪問才能生效,若是放在context中直接報404異常(404表明應該能訪問到,可是不存在該servlet地址).   只能猜想,不用該servlet就沒法讓外部應用訪問到該地址,也許地址必須經過servlet的暴露才能訪問到.

相關文章
相關標籤/搜索