web工程父子容器
邏輯層次關係在計算機中是普遍存在的,比如在容器上。
Spring和Spring MVC 已經成為web工程bean管理和MVC的標準框架。
Spring的容器負責管理bean,而bean是Spring容器管理的基本單元。Spring容器常用ApplicationContext實現,而Spring MVC也會單獨創建Application作為容器。
可知,容器可以有多個。Spring容器和SpringMVC容器是上下層的父子關係。Spring容器是父容器(根容器),SpringMVC容器則作為子容器。父容器不能看見子容器中的bean,而子容器則可以看見父容器中的bean。
為了更好地理解父子容器的層次關係,我們從容器的載入過程講起。
一個web應用需要部署在web容器里,web容器為其提供了一個全局的ServletContext,這是Spring容器的宿主環境。
關於ServletContext,可以看相關注釋。
Defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file.
web.xml是根配置文件,在裡面有關於Spring容器載入的配置。
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value></context-param><listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
監聽器ContextLoaderListener會監聽web容器初始化事件,其contextInitialized方法會調用,在這個方法中,spring會生成根上下文(bean空間),即WebApplicationContext。WebApplicationContext只是介面類,其實際的實現類是XmlWebApplicationContext。
WebApplicationContext會管理bean,bean定義的配置由contextConfigLocation指定。根容器初始化以後,Spring會以WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE為屬性Key,將其存儲到ServletContext中,便於獲取。
SpringMVC相關配置如下:
<servlet> <servlet-name>XXXX</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup></servlet>
contextLoaderListener初始化以後,會初始化web.xml中的servlet。servlet可以配置多個,載入順序按照load-on-startup來執行,比如DispatcherServlet就配置在servlet里,它初始化的時候從ServletContext找到根上下文WebApplicationContext作為自己的父上下文,然後建立自己的上下文,持有和管理SpringMVC相關的bean。
完整的載入順序:ServletContext -> context-param -> listener-> filter -> servlet
容器布局的根本是確定bean的使用範圍。
傳統型
父容器:管理業務邏輯層bean和持久層,比如bean數據源,服務層,Dao層,事務的bean
子容器:管理視圖控制層的bean,即MVC相關的controller的bean。
事務的bean在父容器中,它無法訪問子容器中的Controller,所以無法對Controller進行事務管理(基於AOP技術)。
激進型
父容器:不管理bean
子容器:管理所有bean
在以增刪改查為主業務的系統里,Dao層介面,Dao層實現類,Service層介面,Service層實現類,Action父類,Action類。再加上眾多的O(vopoo)和jsp頁面,在滿足分層的前提下,做一些相對較小功能時會變得比較麻煩。所以激進型方案就出現了,沒有介面,沒有Service層,沒有眾多的O(vopoo),事務管理也放到了Controller中。
怎樣選擇合適的容器布局?大項目求穩,小項目求快。
推薦閱讀: