1、先說ServletContexthtml
javaee標準規定了,servlet容器須要在應用項目啓動時,給應用項目初始化一個ServletContext做爲公共環境容器存放公共信息。ServletContext中的信息都是由容器提供的。java
舉例:web
經過自定義contextListener獲取web.xml中配置的參數
1.容器啓動時,找到配置文件中的context-param做爲鍵值對放到ServletContext中
2.而後找到listener,容器調用它的contextInitialized(ServletContextEvent event)方法,執行其中的操做
例如:在web.xml中配置
複製代碼spring
<context-param> <param-name>key</param-name> <param-value>value123</param-value> </context-param> <listener> <listener-class>com.brolanda.contextlistener.listener.ContextListenerTest</listener-class> </listener>
配置好以後,在該類中獲取對應的參數信息
複製代碼express
package com.brolanda.contextlistener.listener; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class ContextListenerTest implements ServletContextListener { public void contextDestroyed(ServletContextEvent event) { System.out.println("*************destroy ContextListener*************"); } @SuppressWarnings("unused") public void contextInitialized(ServletContextEvent event) { System.out.println("*************init ContextListener*************"); ServletContext servletContext = event.getServletContext(); System.out.println("key:"+servletContext.getInitParameter("key")); } }
複製代碼
執行流程:spring-mvc
web.xml在<context-param></context-param>標籤中聲明應用範圍內的初始化參數mvc
1.啓動一個WEB項目的時候,容器(如:Tomcat)會去讀它的配置文件web.xml.讀兩個節點: <listener></listener> 和 <context-param></context-param>
2.緊接着,容器建立一個ServletContext(上下文)。在該應用內全局共享。
3.容器將<context-param></context-param>轉化爲鍵值對,並交給ServletContext.app
4.容器建立<listener></listener>中的類實例,即建立監聽.該監聽器必須實現自ServletContextListener接口
5.在監聽中會有contextInitialized(ServletContextEvent event)初始化方法
在這個方法中得到ServletContext = ServletContextEvent.getServletContext();this
「context-param的值」 = ServletContext.getInitParameter("context-param的鍵");
6.獲得這個context-param的值以後,你就能夠作一些操做了.注意,這個時候你的WEB項目尚未徹底啓動完成.這個動做會比全部的Servlet都要早.換句話說,這個時候,你對<context-param>中的鍵值作的操做,將在你的WEB項目徹底啓動以前被執行.spa
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")取得
2、spring上下文容器配置
spring爲咱們提供了實現ServletContextListener接口的上下文初始化監聽器:org.springframework.web.context.ContextLoaderListener
spring爲咱們提供的IOC容器,須要咱們指定容器的配置文件,而後由該監聽器初始化並建立該容器。要求你指定配置文件的地址及文件名稱,必定要使用:contextConfigLocation做爲參數名稱。
<context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml,/WEB-INF/action-servlet.xml,/WEB-INF/jason-servlet.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
複製代碼
該監聽器,默認讀取/WEB-INF/下的applicationContext.xml文件。可是經過context-param指定配置文件路徑後,便會去你指定的路徑下讀取對應的配置文件,並進行初始化。
3、spring上下文容器配置後,初始化了什麼?
既然,ServletContext是由Servlet容器初始化的,那spring的ContextLoaderListener又作了什麼初始化呢?
一、servlet容器啓動,爲應用建立一個「全局上下文環境」:ServletContext 二、容器調用web.xml中配置的contextLoaderListener,初始化WebApplicationContext上下文環境(即IOC容器),加載context-param指定的配置文件信息到IOC容器中。WebApplicationContext在ServletContext中以鍵值對的形式保存 三、容器初始化web.xml中配置的servlet,爲其初始化本身的上下文信息servletContext,並加載其設置的配置信息到該上下文中。將WebApplicationContext設置爲它的父容器。 四、此後的全部servlet的初始化都按照3步中方式建立,初始化本身的上下文環境,將WebApplicationContext設置爲本身的父上下文環境。
對於做用範圍而言,在DispatcherServlet中能夠引用由ContextLoaderListener所建立的ApplicationContext中的內容,而反過來不行。
當Spring在執行ApplicationContext的getBean時,若是在本身context中找不到對應的bean,則會在父ApplicationContext中去找。這也解釋了爲何咱們能夠在DispatcherServlet中獲取到由ContextLoaderListener對應的ApplicationContext中的bean。
4、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中:
<context:component-scan base-package="com.linkage.edumanage"> <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation" /> </context:component-scan> spring-mvc.xml中: <context:component-scan base-package="com.brolanda.cloud" use-default-filters="false"> <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation" /> </context:component-scan>