Java EE平臺構建於Java SE平臺之上,Java EE平臺提供一組API和運行環境來開發和運行大規模的,多層的,可擴展的,可靠的和安全的網絡應用程序。這裏會不斷收集和更新JavaEE基礎相關的面試題,目前已收集84題。javascript
Onsubmit:提交
Onblur:失去焦點
Onclick:單擊
Onload:加載頁面
Onchange:內容改變
onMouseMove:鼠標移動
onMouseOver:鼠標通過
onMouseOut:鼠標移出
onselect:下拉選項被選中複製代碼
history.go(0)
location.reload()複製代碼
前進html
history.go(1)
history.forward複製代碼
後退前端
History.go(-1)
History.back複製代碼
Location.href=url
History.go(url)java
Document.getElementById()
Document.getElementsByName()
Document.getElementsByTagName()複製代碼
Onsubmit=「return false」web
$:匹配字符串結束的位置
^:匹配字符串開始的位置
*:匹配零次或者屢次
+:匹配至少一次
?:匹配零次或者一次
.:匹配除換行符 \n以外的任何單字符
{n}:n 是一個非負整數,匹配肯定的 n 次
{n,m}:m 和 n 均爲非負整數,表示最多和最少匹配次數,其中n <= m
\w:匹配單個字符(a-z,0-9,_)
\W:與\w相反
\d:匹配數字
\D:與\d相反複製代碼
DELETE:選擇性地刪除數據,當刪除整張表的數據時效率較低;只能刪除整張表的數據,可是效率高於使用DELETE語句;不能選擇性地刪除。當truncate執行刪除以後,自動生成的主鍵值從新從默認值開始。面試
Java API解析xml主要有兩種方式;正則表達式
Dom解析:一次性加載整個文檔,生成樹形結構。在生成的文檔對象中,能夠對節點進行增刪改查的操做。當xml文本當較小的時候,可使用dom解析。spring
Sax解析:基於事件的解析方式,解析速度比較快,解析的文檔大小理論上是沒有限制的。sql
還有一些開源的技術能夠解析xml,dom4j或者jdom。數據庫
表的設計要規範,即要符合數據庫設計三範式。
適當創建索引,在頻繁做爲檢索條件,更新較少的字段上創建索引,以提升查詢速度。
分表查詢,有水平分割、垂直分割。
讀寫分離,讀(read)、寫(create、update、delete)。
創建存儲過程。複製代碼
Json(javascript simple object notation):輕量級的數據交換格式。
使用{}實例化一個json對象,json對象多個元素使用逗號隔開,每一個元素都是一個鍵值對
使用json-lib、gson、jackson能夠解析json對象。須要將json對象轉換成一個java對象,使用java對象訪問屬性。
全部的索引都是爲了更快地檢索數據,索引存放在索引頁中,數據存放在數據頁中,索引以B(balance)樹的形式存儲
彙集索引:彙集索引用於決定數據表中的物理存儲順序,一張表最多有一個彙集索引。彙集索引的字段值儘可能不能修改,由於修改後,由於修改後數據表的物理順序須要重寫排序。一般主鍵就是彙集索引
非彙集索引:非彙集索引的關鍵自是index,不會決定表的物理存儲順序,在一張表內最多能夠有249個非彙集索引。
能夠。可是隻能有一個public類,並且public修飾的類名與文件名必須一致
Poi:操做office文檔
Jfreechat:生成各類圖表
Ckeditor:論壇中的富文本輸入框
Lucena:用於搜索技術
Pinyin4j:操做漢字的拼音複製代碼
事務:
單個邏輯單元執行的一系列操做,要麼所有執行,要麼所有不執行。複製代碼
特色:
原子性(Atomicity):事務中各元素不可分割,所有執行成功或者撤銷全部的操做
一致性(Consistency):事務完成後數據保持一致的狀
隔離性(Isolation):事務是相對獨立的,對某數據進行修改時,其餘事務不變
持久性(Durability):事務完成後對系統的影響是永久性的。複製代碼
但一個業務邏輯包括多個數據庫操做的時候,並且須要保證每一個數據表操做都執行的成功進行下一個操做,這個時候可使用事務
操做dom,改變dom的結構
指令:<%@ %>
腳本:<% %>
表達式:<%=%>
聲明:<%! %>
註釋:<% -- %>
動做:<jsp:動做名稱 屬性=」」>
靜態內容:html內容複製代碼
Page
pageContext
request
response
out
session
application
config
exception複製代碼
用於處理JSP文件執行時發生的全部錯誤和異常,只有在page指令中設置isErrorPage值爲true的頁面中才能夠被使用,在通常的JSP頁面中使用該對象,將沒法編譯JSP文件。
Get請求發送的文本內容大小有限制,而post請求沒有限制
Get請求的請求參數會出如今url路徑中,而發送post請求時,參數不會顯示在url路徑中
Get安全係數較低,可是效率較高。Post安全係數較高,但效率較低
Get請求只能發送字符串,post請求能夠提交二進制數據複製代碼
應用層
表示層
會話層
傳輸層
網絡層
數據鏈路層
物理層
(物理層是最底層,應用層是最高層)複製代碼
TCP/IP協議
IPX/SPX協議
NetBEUI協議複製代碼
TCP 是面向鏈接的傳輸層協議
每一條 TCP 鏈接只能有兩個端點(endpoint),每一條 TCP 鏈接只能是點對點的(一對一)
TCP 提供可靠交付的服務
TCP 提供全雙工通訊
面向字節流複製代碼
TCP編程
UDP編程複製代碼
TCP協議:傳輸控制協議,提供可靠無差錯的數據傳輸,效率較低
UDP協議:用戶數據報協議,不可靠的數據傳輸,效率較高複製代碼
服務器程序建立一個ServerSocket,而後再用accept方法等待客戶來鏈接
客戶端程序建立一個Socket並請求與服務器創建鏈接
服務器接收客戶的鏈接請求,並建立一個新的Socket與該客戶創建專線鏈接
剛纔創建了鏈接的兩個Socket在一個線程上對話
服務器開始等待新的鏈接請求複製代碼
繼承Thread類
實現Runnable接口
推薦使用Runnable接口複製代碼
Synchronized關鍵字在方法簽名上,能夠防止多個線程同時訪問這個對象的synchronized修飾的方法。若是一個對象有多個synchronized方法,只要一個線程訪問其中的一個同步方法,那麼其餘線程就不能訪問對象其餘的任何一個同步方法。不一樣對象實例的synchronize方法是互不干擾的,也就是說,其餘對象還能夠訪問這個類中的同步方法。
Synchronized若是修飾的是靜態方法,防止多個線程同時訪問這個類中的靜態同步方法,它對類中全部對象都能起做用。也就是說,只有一個對象一個線程能夠訪問靜態同步方法
Synchronized修飾方法中的某段代碼塊,只對當前代碼塊實行互斥訪問。當多個線程同步訪問同步代碼塊,同一時間只能有一個線程獲得執行,其餘線程必須等待當前線程執行完代碼塊以後才能執行。當一個線程訪問同步代碼快時,其餘線程能夠訪問非同步的代碼。當一個線程訪問同步代碼塊時,那麼其餘線程訪問對其餘同步代碼塊的訪問將會被阻塞
Synchronized關鍵字是不能繼承的,若是父類的synchronized在繼承時並不自動是synchronized修飾的,須要顯示地聲明。
Synchronized修飾this時,會獲得這個對象的對象鎖,當一個線程訪問時,那麼其餘線程訪問對象的全部同步代碼塊或者同步方法,將會被阻塞。
在一個應用程序中初始化一個線程集合,而後在須要執行新的任務時重用線程池中的線程,而不是建立一個新的線程。線程池中的每一個線程都有被分配一個任務,一旦任務完成,線程就回到線程池中,等待下一次的任務分配
遊標是sql查詢結果集的一個指針,與select語句相關聯。
遊標關鍵字是cursor,主要包含兩個部分:遊標結果集和遊標位置。
遊標結果集:執行select語句後的查詢結果
遊標位置:一個指向遊標結果集內某條記錄的指針。複製代碼
遊標主要有兩個狀態:打開和關閉。
只有當遊標處於打開狀態時,纔可以操做結果集中的數據
當遊標關閉後,查詢結果集就不存在了複製代碼
定義遊標
打開遊標
操做遊標數據
關閉遊標複製代碼
Mulitipart/form-data
_blank:在新的窗口打開網頁
_self:在本頁面打開新網頁
_parent:在父frameset框架打開網頁
_top:去掉全部頁面框架,使用document.htnl替代frameset文檔複製代碼
_top
加載:判斷servlet實例是否存在,若是不存在,就加載serlvet
實例化:
初始化
服務
銷燬複製代碼
Init()
Service()
doGet或者doPost
destroy複製代碼
新建
就緒
運行
死亡
阻塞複製代碼
preparedStatement會預編譯sql語句,可以提升批量的數據操做的執行效率,Statement執行slq的時候才進行編譯
Preparedstatement在第一次執行sql的時候,比較耗費資源。若是隻對數據庫進行一次操做,使用statement比較好。
Statement會出現sql注入的問題,使用preparedstatment能夠解決sql注入
Session保存在服務端,cookie保存在客戶端
Session保存是對象,cookie只能保存字符串
Session不能設置路徑,cookie能夠設置保存路徑。同一個網站不一樣網頁的cookie能夠保存到不通的路機構下,彼此是沒法相互訪問的。
Session在服務器關閉後會自動消失,cookie則不會。複製代碼
存儲過程的關鍵自是procedure,函數關鍵字是function 函數必須有返回值,存儲過程沒有返回值,可是有傳出參數 函數注重的是結果,存儲過程注重的是過程 函數能夠在select語句中直接使用,而存儲過程則不能複製代碼
Session
Cookie
表單隱藏域
url重寫複製代碼
PageContext
Request
Session
Application複製代碼
統一資源定位符
http://localhost:8080/myWeb/index.html:協議+主機地址+端口+項目名稱+資源名稱複製代碼
Tomcat
Jboss
Weblogic
Glassfish複製代碼
能夠將web項目打包成.war文件
把war文件放在webapps文件夾中複製代碼
在tomcat根目錄的conf文件夾內打開server.xml文件,修改Connector節點的port屬性
請求轉發只能將請求轉發給同一個Web應用中的其餘資源,而重定向不只能夠定向到當前應用程序中的其餘資源,也能夠重定向到其餘站點上的資源。
重定向結束後,瀏覽器地址欄顯示URL會發生改變,由初始的URL地址變成重定向的目標URL。而請求轉發過程結束後,瀏覽器地址欄保持初始的URL地址不變。
請求轉發的發起者和接受者之間共享相同的HttpServletRequest實例和HttpServletResponse實例,而重定向的發起者和接受者使用各自的HttpServletRequest實例和HttpServletResponse實例。
轉發是一次請求,重定向是二次請求。轉發是在服務器進行的,重定向在客服端進行的。
上傳文件主要用的是開源組件,如apache commoms fileupload或者jspformatupload
200:請求成功
400:不是正確的請求,大多狀況下表示參數錯誤
404:找不到請求資源
500:服務器內部錯誤
403:服務器拒絕
405:請求的method不支持
504:服務器臨時不可用複製代碼
Include
Taglib
Page複製代碼
Session.invalidate()
使用jstl標籤庫,使用numberformat或者dateformat標籤
線程同步:同時只有一條線程執行一個任務
線程異步:同時有多條線程能夠執行執行任務複製代碼
同步任務:當前任務沒有完成以前,其餘任務不可以執行
異步任務:當前任務沒有完成,任然能夠能夠發送一個新的請求複製代碼
過濾器:在請求發送以後,處理以前對請求的一次攔截,能夠更改請求狀態或者參數值等。
建立過濾器:實現filter接口,重寫doFilter方法,最後在web.xml中配置過濾器
Integer是int的包裝類型。
Int的默認值是0,integer的默認值是null複製代碼
使用junit
Select top 3 * from tb_name where id not in (select top 3 id from tb_name)
ava Web開發中的監聽器(listener)就是application、session、request三個對象建立、銷燬或者往其中添加修改刪除屬性時自動執行代碼的功能組件,以下所示:
ServletContextListener:對Servlet上下文的建立和銷燬進行監聽。
ServletContextAttributeListener:監聽Servlet上下文屬性的添加、刪除和替換。
HttpSessionListener:對Session的建立和銷燬進行監聽。複製代碼
靜態包含是經過JSP的include指令包含頁面,動態包含是經過JSP標準動做
靜態包含是編譯時包含,若是包含的頁面不存在則會產生編譯錯誤,並且兩個頁面的"contentType"屬性應保持一致,由於兩個頁面會合二爲一,只產生一個class文件,所以被包含頁面發生的變更再包含它的頁面更新前不會獲得更新。
動態包含是運行時包含,能夠向被包含的頁面傳遞參數,包含頁面和被包含頁面是獨立的,會編譯出兩個class文件,若是被包含的頁面不存在,不會產生編譯錯誤,也不影響頁面其餘部分的執行。
能夠經過請求對象(HttpServletRequest)的getParameter()方法經過參數名得到參數值。若是有包含多個值的參數(例如複選框),能夠經過請求對象的getParameterValues()方法得到。固然也能夠經過請求對象的getParameterMap()得到一個參數名和參數值的映射(Map)。
經過請求對象(ServletRequest)的setCharacterEncoding(String)方法能夠設置請求的編碼,其實要完全解決亂碼問題就應該讓頁面、服務器、請求和響應、Java程序都使用統一的編碼,最好的選擇固然是UTF-8;經過響應對象(ServletResponse)的setContentType(String)方法能夠設置響應內容的類型,固然也能夠經過HttpServletResponsed對象的setHeader(String, String)方法來設置。
從表面上看,Web Service就是一個應用程序,它向外界暴露出一個可以經過Web進行調用的API。這就是說,你可以用編程的方法透明的調用這個應用程序,不須要了解它的任何細節,跟你使用的編程語言也沒有關係。例如能夠建立一個提供天氣預報的Web Service,那麼不管你用哪一種編程語言開發的應用均可以經過調用它的API並傳入城市信息來得到該城市的天氣預報。之因此稱之爲Web Service,是由於它基於HTTP協議傳輸數據,這使得運行在不一樣機器上的不一樣應用無須藉助附加的、專門的第三方軟件或硬件,就可相互交換數據或集成。
對象關係映射(Object-Relational Mapping,簡稱ORM)是一種爲了解決程序的面向對象模型與數據庫的關係模型互不匹配問題的技術
SessionFactory對應Hibernate的一個數據存儲的概念,它是線程安全的,能夠被多個線程併發訪問。SessionFactory通常只會在啓動的時候構建。對於應用程序,最好將SessionFactory經過單例模式進行封裝以便於訪問。Session是一個輕量級非線程安全的對象(線程間不能共享session),它表示與數據庫進行交互的一個工做單元。Session是由SessionFactory建立的,在任務完成以後它會被關閉。Session是持久層服務對外提供的主要接口。Session會延遲獲取數據庫鏈接(也就是在須要的時候纔會獲取)。爲了不建立太多的session,可使用ThreadLocal將session和當前線程綁定在一塊兒,這樣可讓同一個線程得到的老是同一個session。Hibernate 3中SessionFactory的getCurrentSession()方法就能夠作到。
若是沒有找到符合條件的記錄,get方法返回null,load方法拋出異常。
get方法直接返回實體類對象,load方法返回實體類對象的代理。
在Hibernate 3以前,get方法只在一級緩存中進行數據查找,若是沒有找到對應的數據則越過二級緩存,直接發出SQL語句完成數據讀取;load方法則能夠從二級緩存中獲取數據;從Hibernate 3開始,get方法再也不是對二級緩存只寫不讀,它也是能夠訪問二級緩存的。
瞬時態(transient)
持久態(persistent)
遊離態(detached)複製代碼
瞬時態的實例能夠經過調用save()、persist()或者saveOrUpdate()方法變成持久態;遊離態的實例能夠經過調用 update()、saveOrUpdate()、lock()或者replicate()變成持久態。save()和persist()將會引起SQL的INSERT語句,而update()或merge()會引起UPDATE語句。save()和update()的區別在於一個是將瞬時態對象變成持久態,一個是將遊離態對象變爲持久態。merge()方法能夠完成save()和update()方法的功能,它的意圖是將新的狀態合併到已有的持久化對象上或建立新的持久化對象。
對於persist()方法,
persist()方法把一個瞬時態的實例持久化,可是並不保證標識符被馬上填入到持久化實例中,標識符的填入可能被推遲到flush的時間;
persist()方法保證當它在一個事務外部被調用的時候並不觸發一個INSERT語句,當須要封裝一個長會話流程的時候,persist()方法是頗有必要的;
save()方法不保證第②條,它要返回標識符,因此它會當即執行INSERT語句,無論是在事務內部仍是外部。至於lock()方法和update()方法的區別,update()方法是把一個已經更改過的脫管狀態的對象變成持久狀態;lock()方法是把一個沒有更改過的脫管狀態的對象變成持久狀態。
Session在調用數據庫查詢功能以前,首先會在一級緩存中經過實體類型和主鍵進行查找,若是一級緩存查找命中且數據狀態合法,則直接返回;
若是一級緩存沒有命中,接下來Session會在當前NonExists記錄(至關於一個查詢黑名單,若是出現重複的無效查詢能夠迅速作出判斷,從而提高性能)中進行查找,若是NonExists中存在一樣的查詢條件,則返回null;
若是一級緩存查詢失敗則查詢二級緩存,若是二級緩存命中則直接返回;
若是以前的查詢都未命中,則發出SQL語句,若是查詢未發現對應記錄則將這次查詢添加到Session的NonExists中加以記錄,並返回null;
根據映射配置和SQL語句獲得ResultSet,並建立對應的實體對象;
將對象歸入Session(一級緩存)的管理;
若是有對應的攔截器,則執行攔截器的onLoad方法;
若是開啓並設置了要使用二級緩存,則將數據對象歸入二級緩存;
返回數據對象。
list()方法沒法利用一級緩存和二級緩存(對緩存只寫不讀),它只能在開啓查詢緩存的前提下使用查詢緩存;iterate()方法能夠充分利用緩存,若是目標數據只讀或者讀取頻繁,使用iterate()方法能夠減小性能開銷。
list()方法不會引發N+1查詢問題,而iterate()方法可能引發N+1查詢問題
延遲加載就是並非在讀取的時候就把數據加載進來,而是等到使用時再加載。Hibernate使用了虛擬代理機制實現延遲加載,咱們使用Session的load()方法加載數據或者一對多關聯映射在使用延遲加載的狀況下從一的一方加載多的一方,獲得的都是虛擬代理,簡單的說返回給用戶的並非實體自己,而是實體對象的代理。代理對象在用戶調用getter方法時纔會去數據庫加載數據。但加載數據就須要數據庫鏈接。而當咱們把會話關閉時,數據庫鏈接就同時關閉了。
延遲加載與session關閉的矛盾通常能夠這樣處理:
關閉延遲加載特性。這種方式操做起來比較簡單,由於Hibernate的延遲加載特性是能夠經過映射文件或者註解進行配置的,但這種解決方案存在明顯的缺陷。首先,出現"no session or session was closed"一般說明系統中已經存在主外鍵關聯,若是去掉延遲加載的話,每次查詢的開銷都會變得很大。
在session關閉以前先獲取須要查詢的數據,可使用工具方法Hibernate.isInitialized()判斷對象是否被加載,若是沒有被加載則可使用Hibernate.initialize()方法加載對象。
使用攔截器或過濾器延長Session的生命週期直到視圖得到數據。Spring整合Hibernate提供的OpenSessionInViewFilter和OpenSessionInViewInterceptor就是這種作法。
制定合理的緩存策略(二級緩存、查詢緩存)。
採用合理的Session管理機制。
儘可能使用延遲加載特性。
設定合理的批處理參數。
若是能夠,選用UUID做爲主鍵生成器。
若是能夠,選用樂觀鎖替代悲觀鎖。
在開發過程當中, 開啓hibernate.show_sql選項查看生成的SQL,從而瞭解底層的情況;開發完成後關閉此選項。
考慮數據庫自己的優化,合理的索引、恰當的數據分區策略等都會對持久層的性能帶來可觀的提高,但這些須要專業的DBA(數據庫管理員)提供支持。複製代碼
Hibernate的Session提供了一級緩存的功能,默認老是有效的,當應用程序保存持久化實體、修改持久化實體時,Session並不會當即把這種改變提交到數據庫,而是緩存在當前的Session中,除非顯示調用了Session的flush()方法或經過close()方法關閉Session。經過一級緩存,能夠減小程序與數據庫的交互,從而提升數據庫訪問性能。
SessionFactory級別的二級緩存是全局性的,全部的Session能夠共享這個二級緩存。不過二級緩存默認是關閉的,須要顯示開啓並指定須要使用哪一種二級緩存實現類(可使用第三方提供的實現)。一旦開啓了二級緩存並設置了須要使用二級緩存的實體類,SessionFactory就會緩存訪問過的該實體類的每一個對象,除非緩存的數據超出了指定的緩存空間。
一級緩存和二級緩存都是對整個實體進行緩存,不會緩存普通屬性,若是但願對普通屬性進行緩存,可使用查詢緩存。查詢緩存是將HQL或SQL語句以及它們的查詢結果做爲鍵值對進行緩存,對於一樣的查詢能夠直接從緩存中獲取數據。查詢緩存默認也是關閉的,須要顯示開啓。
#將傳入的數據都當成一個字符串,會對傳入的數據自動加上引號;$將傳入的數據直接顯示生成在SQL中。注意:使用$佔位符可能會致使SQL注射攻擊,能用#的地方就不要使用$,寫order by子句的時候應該用$而不是#。、
IoC叫控制反轉,是Inversion of Control的縮寫,DI(Dependency Injection)叫依賴注入,是對IoC更簡單的詮釋。控制反轉是把傳統上由程序代碼直接操控的對象的調用權交給容器,經過容器來實現對象組件的裝配和管理。所謂的"控制反轉"就是對組件對象控制權的轉移,從程序代碼自己轉移到了外部容器,由容器來建立對象並管理對象之間的依賴關係。依賴注入的基本原則是應用組件不該該負責查找資源或者其餘依賴的協做對象。配置對象的工做應該由容器負責,查找資源的邏輯應該從應用組件的代碼中抽取出來,交給容器來完成。DI是對IoC更準確的描述,即組件之間的依賴關係由容器在運行期決定,形象的來講,即由容器動態的將某種依賴關係注入到組件之中。
依賴注入能夠經過setter方法注入(設值注入)、構造器注入和接口注入三種方式來實現,Spring支持setter注入和構造器注入,一般使用構造器注入來注入必須的依賴關係,對於可選的依賴關係,則setter注入是更好的選擇,setter注入須要類提供無參構造器或者無參的靜態工廠方法來建立對象。
no:不進行自動裝配,手動設置Bean的依賴關係。
byName:根據Bean的名字進行自動裝配。
byType:根據Bean的類型進行自動裝配。
constructor:相似於byType,不過是應用於構造器的參數,若是正好有一個Bean與構造器的參數類型相同則能夠自動裝配,不然會致使錯誤。
autodetect:若是有默認的構造器,則經過constructor的方式進行自動裝配,不然使用byType的方式進行自動裝配。複製代碼
AOP(Aspect-Oriented Programming)指一種程序設計範型,該範型以一種稱爲切面(aspect)的語言構造爲基礎,切面是一種新的模塊化機制,用來描述分散在對象、類或方法中的橫切關注點(crosscutting concern)。
Singleton:Bean以單例的方式存在
Prototype:表示每次從容器中調用Bean時,都會返回一個新的實例,prototype一般翻譯爲原型
Request:每次HTTP請求都會建立一個新的Bean
Session:同一個HttpSession共享同一個Bean,不一樣的HttpSession使用不一樣的Bean
globalSession:同一個全局Session共享一個Bean複製代碼
首先須要在Spring配置文件中增長配置:
用@Component、@Controller、@Service、@Repository註解來標註須要由Spring IoC容器進行對象託管的類。
@Controller一般用於控制器
@Service一般用於業務邏輯類
@Repository一般用於DAO類
普通的類用@Component來標註。複製代碼
Spring支持編程式事務管理和聲明式事務管理。聲明式事務管理要優於編程式事務管理,儘管在靈活性方面它弱於編程式事務管理,由於編程式事務容許經過代碼控制業務。
客戶端的全部請求都交給前端控制器DispatcherServlet來處理,它會負責調用系統的其餘模塊來真正處理用戶的請求。
DispatcherServlet收到請求後,將根據請求的信息(包括URL、HTTP協議方法、請求頭、請求參數、Cookie等)以及HandlerMapping的配置找處處理該請求的Handler(任何一個對象均可以做爲請求的Handler)。
在這個地方Spring會經過HandlerAdapter對該處理器進行封裝。
HandlerAdapter是一個適配器,它用統一的接口對各類Handler中的方法進行調用。
Handler完成對用戶請求的處理後,會返回一個ModelAndView對象給DispatcherServlet,ModelAndView顧名思義,包含了數據模型以及相應的視圖的信息。
ModelAndView的視圖是邏輯視圖,DispatcherServlet還要藉助ViewResolver完成從邏輯視圖到真實視圖對象的解析工做。
當獲得真正的視圖對象後,DispatcherServlet會利用視圖對象對模型數據進行渲染。
客戶端獲得響應,多是一個普通的HTML頁面,也能夠是XML或JSON字符串,還能夠是一張圖片或者一個PDF文件。
Spring IoC容器找到關於Bean的定義並實例化該Bean。
pring IoC容器對Bean進行依賴注入。
若是Bean實現了BeanNameAware接口,則將該Bean的id傳給setBeanName方法。
若是Bean實現了BeanFactoryAware接口,則將BeanFactory對象傳給setBeanFactory方法。
若是Bean實現了BeanPostProcessor接口,則調用其postProcessBeforeInitialization方法。
若是Bean實現了InitializingBean接口,則調用其afterPropertySet方法。
若是有和Bean關聯的BeanPostProcessors對象,則這些對象的postProcessAfterInitialization方法被調用。
當銷燬Bean實例時,若是Bean實現了DisposableBean接口,則調用其destroy方法。複製代碼