1. 程式人生 > >springmvc application 理解

springmvc application 理解

spring mvc裡的root/child WebApplicationContext的繼承關係

  1. 在傳統的spring mvc程式裡會有兩個WebApplicationContext,一個是parent,從applicationContext.xml里加載的,一個是child,從servlet-context.xml里加載的。兩者是繼承關係,child WebApplicationContext 可以通過getParent()函式獲取到root WebApplicationContext。
    簡單地說child WebApplicationContext裡的bean可以注入root WebApplicationContext裡的bean,而parent WebApplicationContext的bean則不能注入chile WebApplicationContext裡的bean。

一個典型的web.xml的內容是:

<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:/applicationContext.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1
</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>

其中root WebApplicationContext是通過listener初始化的,child WebApplicationContext是通過servlet初始化的。

而在applicationContext.xml裡通常只component-scan非Controller的類,如:

<context:component-scan base-package="io.github.test">
    <context:exclude-filter expression="org.springframework.stereotype.Controller"
        type="annotation" />
    <context:exclude-filter type="annotation"
        expression="org.springframework.web.bind.annotation.ControllerAdvice" />
</context:component-scan>

在servlet-context.xml裡通常只component-scan Controller類,如:

<context:component-scan base-package="io.github.test.web" use-default-filters="false">
    <context:include-filter expression="org.springframework.stereotype.Controller"
        type="annotation" />
    <context:include-filter type="annotation"
        expression="org.springframework.web.bind.annotation.ControllerAdvice" />
</context:component-scan>

如果不這樣子分別component-scan的話,可能會出現Bean重複初始化的問題。上面是Spring官方開始時推薦的做法。

root/child WebApplicationContext繼承關係帶來的麻煩

root WebApplicationContext裡的bean可以在不同的child WebApplicationContext裡共享,而不同的child WebApplicationContext裡的bean區不干擾,這個本來是個很好的設計。

但是實際上有會不少的問題:
* 不少開發者不知道Spring mvc裡分有兩個WebApplicationContext,導致各種重複構造bean,各種bean無法注入的問題。
* 有一些bean,比如全域性的aop處理的類,如果先root WebApplicationContext裡初始化了,那麼child WebApplicationContext裡的初始化的bean就沒有處理到。如果在chile WebApplicationContext裡初始化,在root WebApplicationContext裡的類就沒有辦法注入了。
* 區分哪些bean放在root/child很麻煩,不小心容易搞錯,而且費心思。

一勞永逸的解決辦法:bean都由root WebApplicationContext載入

在一次配置metrics-spring時,對配置@EnableMetrics配置在哪個WebApplicationContext裡,感到很蛋疼。最終決定試下把所有的bean,包括Controller都移到root WebApplicationContext,即applicationContext.xml里加載,而servlet-context.xml裡基本是空的。結果發現程式執行完全沒問題。

後面在網上搜索了下,發現有一些相關的討論:

spring boot裡的做法

在spring boot裡預設情況下不需要component-scan的配置,於是猜測在Spring boot裡是不是隻有一個WebApplicationContext?

後面測試下了,發現在spring boot裡預設情況下的確是只有一個WebApplicationContext:
org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext,
所以在spring boot裡省事了很多。

總結

spring 的ApplicationContext繼承機制是一個很好的設計,在很多其它地方都可以看到類似的思路,比如Java的class loader。但是在大部分spring web程式裡,實際上只要一個WebApplicationContext就夠了。如果分開rott/child WebApplicationContext會導致混亂,而沒什麼用。

所以推薦把所有的Service/Controller都移到root WebApplicationContext中初始化。

applicationContext 子類理解

非web環境下的讀取xml定義形式的Bean的類的父類介面是:
ConfigurableApplicationContext
抽象類:
AbstractApplicationContext
AbstractXmlApplicationContext
具體實現類:
GenericApplicationContext 一般讀取方式需要結合ClassPathResource DefaultListableBeanFactory的方式讀取xml 中Bean
FileSystemXmlApplicationContext 從檔案系統中讀取xml
ClassPathXmlApplicationContext 從應用路徑讀取xml
StaticApplicationContext

web環境下讀取xml的方式:(在web環境在ServletContext下添加了WebApplicationContext和)
ConfigurableWebApplicationContext
其下抽象類
AbstractRefreshableWebApplicationContext
實現類:
XmlWebApplicationContext
GenericWebApplicationContext 使用ClassPathResource DefaultListableBeanFactory
GroovyWebApplicationContext 使用application.goovy方式讀取Bean
StaticWebApplicationContext
AnnotationConfigWebApplicationContext
XmlEmbeddedWebApplicationContext
AnnotationConfigEmbeddedWebApplicationContext

在web環境下可以通過listener的方式載入org.springframework.web.context.ContextLoaderListener 建立WebApplicationContext,使用ApplicationContextUtil 工具類在來獲取context,在servelet實現類中可以獲取getServletContext() 獲取ServletContext

相關推薦

springmvc application 理解

spring mvc裡的root/child WebApplicationContext的繼承關係 在傳統的spring mvc程式裡會有兩個WebApplicationContext,一個是parent,從applicationContext.xml里加載

SSM-SpringMVC-04:SpringMVC深入淺出理解HandleMapping(源碼刨析)

model oba else tro finally asn span ror tor ------------吾亦無他,唯手熟爾,謙卑若愚,好學若饑------------- 先從概念理解,從中央調度器,攜帶參數request,調度到HandleMapping

SpringMVC理解

apt 過濾 tro mes 結合 註冊 integer sage 發送請求 SpringMVC工作原理 SpringMvc是基於過濾器對servlet進行了封裝的一個框架,我們使用的時候就是在web.xml文件中配置DispatcherServlet類;SpringM

SpringMVC框架理解

ola ans sub character XML toad this 轉發 org JavaEE體系結構包括四層,從上到下分別是應用層、Web層、業務層、持久層。Struts和SpringMVC是Web層的框架,Spring是業務層的框架,Hibernate和MyBati

01-springMVC概要理解

引言 1. MVC : Model-View-Control 框架性質的C層主要完成的工作有: 封裝web請求為一個數據 呼叫業務邏輯層來處理資料物件 返回資料結果及相應的駛入給使用者 2. 簡要概述springMVC     Spring 的C

SpringMVC理解

都是些個人對SpringMVC的個人理解; @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")  @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")   1

對Spring 及SpringMVC理解

Spring是一個輕型容器(light-weight container),其核心是Bean工廠(Bean Factory),用以構造我們所需要的M(Model)。在此基礎之上,Spring提供了AOP(Aspect-Oriented Programming, 面向層面的

SpringMVC深入理解

Spring3 MVC的優點: 1、Spring3 MVC的學習難度小於Struts2,Struts2用不上的多餘功能太多。呵呵,當然這不是決定因素。 2、Spring3 MVC很容易就可以寫出效能優秀的程式,Struts2要處處小心才可以寫出效能優秀的程式(指MVC部分)

SpringMVC流程理解

SpringMVC工作流程描述     1、前端控制器DispatcherServlet接收請求     2、DispatcherServlet呼叫HandlerMapping獲得該Handler配置    &nbs

springmvc application/octet-stream 問題

錯誤: [ERROR][10:59:32][http-nio-8080-exec-2]interceptor.GlobalAdvice(46) org.springframework.web.HttpMediaTypeNotSupportedException: Cont

【Spring原始碼解析】—— 結合SpringMVC過程理解IOC容器初始化之註解部分探究

前面的文章寫了xml中直接配置bean進行IOC的過程解析,接下來會針對註解進行IOC容器初始化的過程解析 因為會與之前的內容存在部分重疊,因此會針對相同的部分簡略帶過,針對不同的部分做重點說明:   一、Xml的配置和程式碼中的註解配置: applicationContext.xml配置新

逐步理解SpringMVC

gmv 理解 pic hub spa mvc springmvc pri .com http://pic.cnhubei.com/space.php?uid=1774&do=album&id=1358752http://pic.cnhubei.com/spa

Flask源碼解析(理解working outside of application context)

dir IE ide info reference 檢查 acc 想要 inside from flask import Flask, current_app app = Flask(__name__) a = current_app d = current_app

springmvc攔截器使用和原理理解

res ont str ppi lan ati IT 做的 string 與struts2類似,springmvc的攔截器主要作用也是在服務端真正處理請求前後進行一些相關的操作。 例如初始化資源,權限監控,會話設置,菜單獲取,資源清理等。 步驟: 1. 定義攔截器

springboot中配置檔案application.properties的理解

springboot中配置檔案application.properties的理解 前言 Spring Boot使用“習慣優於配置”(專案中存在大量的配置,此外還內建了一個習慣性的配置,讓你無需手動進行配置)的理念讓你的專案快速執行起來。所以,我們要想把Spring Boot玩的溜,就要懂得如

深入淺出地理解springmvc及第一個小例子

Spring MVC框架是有一個MVC框架,通過實現Model-View-Controller模式來很好地將資料、業務與展現進行分離。從這樣一個角度來說,Spring MVC和Struts、Struts2非常類似。Spring MVC的設計是圍繞DispatcherS

【Spring篇02】對於SpringMVC核心原理的理解 & @Controller和@RequestMapping註解

之前在【Web篇08】中提到,SpringMVC的核心就是優化了B/S結構(瀏覽器-伺服器),簡化了Servlet的建立; 瀏覽器可以查詢的路徑:WebContent目錄下的jsp檔案,一般在這個目錄下建立個index.jps作為首頁 伺服器可以查詢的路徑:WEB-INF目錄下的jsp

理解springMVC中的Model和Session屬性

                作為一個javaweb應用的開發者,你快速學習了request(HttpRequest)和Sess

關於SpringMVC中檢視解析器的理解

最近在使用springMVC做一個東西,但是我的spring是剛學,springMVC更是一知半解,尤其對於控制器和檢視間的過程一直搞不清楚,今天有些理解,在這記錄下來. @controller中的@requestMapping"攔截"了相應的請求頁面,並且交給相應的方法處理,方法處理的返回就是

SpringMVC專題——SpringMVC的流程(個人理解

        SpringMVC處理請求: ——》訪問URL首先被DispatcherServlet截獲 ——》DispatcherServlet通過handlerMapping【定位controller,本質map<url,controlle