天天看點

Servlet容器與Web容器詳解

【1】容器

所謂容器(伺服器、中間件等),就是提供一些底層的、業務無關的基本功能,為真正的Servlet提供服務。簡單來說:容器負責根據請求的資訊找到對應的Servlet,傳遞Request和Response參數,調用Servlet的service方法,完成請求的響應。

Servlet規範定義了一個API标準,這一标準的實作通常稱為Servlet容器,比如開源的Tomcat、JBoss。

Web容器更準确的說應該叫web伺服器,它是來管理和部署 web應用的。Web容器最典型的就是tomcat了,Tomcat是web容 器也是servlet容器。

還有一種伺服器叫做應用伺服器,它的功能比web伺服器要強大的多,因為它可以部署EJB應用,可以實作容器管理的事務,一般的應用伺服器 有weblogic和websphere等,它們都是商業伺服器,功能強大但都是收費的。

【2】ServletContext

JavaEE标準規定了,servlet容器需要在應用項目啟動時,給應用項目初始化一個ServletContext作為公共環境容器存放公共資訊。

ServletContext 是Servlet與Servlet容器之間直接通信的接口,Servlet容器在啟動一個web應用時,會為它建立一個ServletContext對象。

每個web應用有唯一的ServletContext對象,同一個web應用的所有Servlet對象共享一個 ServletContext,Servlet對象可以通過它來通路容器中的各種資源

在應用程式中能夠擷取運作環境或容器資訊的對象通常稱之為"上下文對象"。ServletContext中的資訊都是由Web容器提供的,通常是配置web.xml,其執行流程如下所示。

web.xml在​

​<context-param></context-param>​

​标簽中聲明應用範圍内的初始化參數。

  • ① 啟動一個WEB項目的時候,容器(如:Tomcat)會去讀它的配置檔案web.xml.讀兩個節點:​

    ​<listener></listener> 和 <context-param></context-param>​

    ​;
  • ② 緊接着,容器建立一個ServletContext(上下文),在該應用内全局共享。
  • ③ 容器将​

    ​<context-param></context-param>​

    ​轉化為鍵值對,并交給ServletContext.
  • ④ 容器建立​

    ​<listener></listener>​

    ​中的類執行個體,即建立監聽。該監聽器必須實作自​

    ​ServletContextListener​

    ​接口。
  • ⑤ 在監聽中會有​

    ​contextInitialized(ServletContextEvent event)​

    ​初始化方法 在這個方法中獲得這個context-param的值之後,你就可以做一些操作了。
ServletContext = ServletContextEvent.getServletContext();

contextParamValue = ServletContext.getInitParameter("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裡面可以通過ServletContext得到:

String contextParamVale= getServletContext().getInitParameter("context-param")      

第二種參數有兩種取值方式:

  • ① 在servlet的init()方法中通過​

    ​this.getInitParameter("param1")​

    ​取得
  • ② 使用ServletConfig:
ServletConfig config = getServletConfig();
String paramValue=config.getInitParameter("paramName");      

【3】Spring環境下IOC容器

spring環境下通常會配置如下監聽:

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>      

① Web容器啟動,為應用建立一個“全局上下文環境”:ServletContext(即,ApplicationContext);

② 容器調用web.xml中配置的ContextLoaderListener(如果配置了該監聽),根據ServletContext和context-param指定的配置檔案資訊(application.xml)初始化WebApplicationContext上下文環境(即IOC容器)。

Servlet容器與Web容器詳解

WebApplicationContext在ServletContext中以鍵值對的形式儲存;

鍵–WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;

值–webApplicationContext。

③ 容器初始化web.xml中配置的servlet(​

​<load-on-startup>1</load-on-startup>​

​),為其初始化自己的servletConfig(擁有對ServletContext的引用),并加載其設定的參數資訊到該執行個體中。

擷取初始化參數示例如下:

ServletConfig config = getServletConfig();
String paramValue=config.getInitParameter("paramName");      

④ 此後的所有servlet(​

​<load-on-startup>1</load-on-startup>​

​)的初始化都按照3步中方式建立,初始化自己的上下文環境。

當Spring在執行ApplicationContext的getBean時,如果在自己context中找不到對應的bean,則會在父ApplicationContext中去找。

這也解釋了為什麼我們可以在DispatcherServlet中擷取到由ContextLoaderListener對應的ApplicationContext中的bean。