Web容器、Servlet容器、Spring容器、SpringMVC容器之間的關系
以下內容為個人理解,如有誤還請留言指出,不勝感激!
Web容器
web容器(web服務器)主要有:Apache、IIS、Tomcat、Jetty、JBoss、webLogic等,而Tomcat、Jetty、JBoss、webLogic同時也是servlet容器,或者說他們還包含了servlet容器。沒有servlet容器,你也可以用web容器直接訪問靜態頁面,比如安裝一個apache等,但是如果要顯示jsp/servlet,你就要安裝一個servlet容器了,但是光有servlet容器是不夠的,因為它要被解析成html輸出,所以你仍需要一個web容器。大多數servlet容器同時提供了
web容器是管理servlet(通過servlet容器),以及監聽器(Listener)和過濾器(Filter)的。這些都是在web容器的掌控範圍裏。但他們不在spring和springmvc的掌控範圍裏。因此,我們無法在這些類中直接使用Spring註解的方式來註入我們需要的對象,是無效的,web容器是無法識別的。
但我們有時候又確實會有這樣的需求,比如在容器啟動的時候,做一些驗證或者初始化操作,這時可能會在監聽器裏用到bean對象;又或者需要定義一個過濾器做一些攔截操作,也可能會用到bean對象。
那麽在這些地方怎麽獲取
1、
public void contextInitialized(ServletContextEvent sce) { ApplicationContext context = (ApplicationContext) sce.getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); UserService userService = (UserService) context.getBean("userService"); }
2、
public void contextInitialized(ServletContextEvent sce) { WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()); UserService userService = (UserService) webApplicationContext.getBean("userService"); }
註意:以上代碼有一個前提,那就是servlet容器在實例化ConfigListener並調用其方法之前,要確保spring容器已經初始化完畢!而spring容器的初始化也是由Listener(ContextLoaderListener)完成,因此只需在web.xml中先配置初始化spring容器的Listener,然後在配置自己的Listener。
TOMCAT
在Tomcat中有4種級別的容器:Engine,Host,Context和Wrapper。
Engine:整個Catalina Servlet引擎;
Host:包含一個或多個Context容器的虛擬主機;
Context:表示一個Web應用程序,對應著一個Servlet上下文(ServletContext),可以包含多個Wrapper;
Wrapper:表示一個獨立的Servlet;
4個層級接口的標準實現分別是:StandardEngine類,StandardHost類,StandardContext類和StandardWrapper類。它們在org.apache.catalina.core包下。
Tomcat結構目錄
/bin:包含啟動和關閉Tomcat的文件
/conf:包含不同的配置文件:server.xml,web.xml,tomcat-user.xml
/lib:包含Tomcat使用的JAR文件
/logs:包含日誌文件
/webapps:包含應用程序示例及自己開發的程序
/work:包含有JSP生成的Servlet
Servlet容器
Servlet容器是管理servlet對象的。
Servlet容器的作用:
負責處理客戶請求,當客戶請求來到時,Servlet容器獲取請求,然後調用某個Servlet,並把Servlet的執行結果返回給客戶。
使用Servlet容器的原因:
通信支持:利用容器提供的方法,你能輕松的讓servlet與web服務器對話,而不用自己建立serversocket、監聽某個端口、創建流等 等。容器知道自己與web服務器之間的協議,所以你的servlet不用擔心web服務器(如Apache)和你自己的web代碼之間的API,只需要考慮如何在servlet中實現業務邏輯(如處理一個訂單)。
生命周期管理:servlet容器控制著servlet的生與死,它負責加載類、實例化和初始化
servlet,調用servlet方法,以及使servlet實例被垃圾回收,有了servlet容器,你不需要太多的考慮資源管理。
多線程支持:容器會自動為它所接收的每個servlet請求創建一個新的java線程。針對用戶的請求,如果servlet已經運行完相應的http服務方法,這個線程就會結束。這並不是說你不需要考慮線程安全性,其實你還會遇到同步問題,不過這樣能使你少做很多工作。
聲明方式實現安全:利用servlet容器,可以使用xml部署描述文件來配置和修改安全性,而不必將其硬編碼寫到servlet類代碼中。
JSP支持:servlet容器負責將jsp代碼翻譯為真正的java代碼。
Spring容器
Spring容器是管理service和dao的。
SpringMVC容器
SpringMVC容器是管理controller對象的。
Spring容器和SpringMVC容器的關系是父子容器的關系。Spring容器是父容器,SpringMVC容器是子容器。在子容器裏可以訪問父容器裏的對象,但是在父容器裏不可以訪問子容器的對象,說的通俗點就是,在controller裏可以訪問service對象,但是在service裏不可以訪問controller對象。所以這麽看的話,所有的bean,都是被Spring或者SpringMVC容器管理的,他們可以直接註入。然後SpringMVC的攔截器也是SpringMVC容器管理的,所以在SpringMVC的攔截器裏,可以直接註入bean對象。
Servlet容器和ServletContext的關系:
ServletContext是servlet與servlet容器之間的直接通信的接口。Servlet容器在啟動一個Web應用時,會為它創建一個servletContext對象。每個web應用有唯一的servletContext對象。同一個web應用的所有servlet對象共享一個serveltContext,servlet對象可以通過它來訪問容器中的各種資源。
各個容器的創建過程:
1、TOMCAT啟動,Servlet容器隨即啟動,然後讀取server.xml配置文件,啟動裏面配置的web應用,為每個應用創建一個“全局上下文環境”(ServletContext);
2、創建Spring容器實例。調用web.xml中配置的ContextLoaderListener,初始化WebApplicationContext上下文環境(即IOC容器),加載contextparam指定的配置文件信息到IOC容器中。WebApplicationContext在ServletContext中以鍵值對的形式保存。
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:root-context.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
3、創建SpringMVC容器實例。調用web.xml中配置的servlet-class,為其初始化自己的上下文信息,並加載其設置的配置信息到該上下文中。將WebApplicationContext設置為它的父容器。
<!-- springMVC配置 --> <servlet> <servlet-name>appServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:servlet-context.xml</param-value> </init-param>
<init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>allowScriptTagRemoting</param-name > <param-value>true </param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
4、此後的所有servlet的初始化都按照3步中方式創建,初始化自己的上下文環境,將WebApplicationContext設置為自己的父上下文環境。當Spring在執行ApplicationContext的getBean時,如果在自己context中找不到對應的bean,則會在父ApplicationContext中去找。
Web容器、Servlet容器、Spring容器、SpringMVC容器之間的關系