1. 介紹spring框架
Spring是一套為了解決企業(yè)應用開發(fā)的復雜性而創(chuàng)建的框架,特點是分層的架構(gòu)纳猪,允許用戶在不同層面使用不同的組件進行組合陋葡。同時通過IOC容器來降低耦合,簡化開發(fā)救拉。利用AOP來進行切面編程統(tǒng)一管理通用模塊难审。
2.Spring中AOP的應用場景、Aop原理亿絮、好處告喊?
主要是兩種,一種是JDK動態(tài)代理派昧,一種是Cglib代理黔姜。
兩者的區(qū)別:
- JDK動態(tài)代理只能代理實現(xiàn)了接口的類,動態(tài)代理類的字節(jié)碼在程序運行時由Java反射機制動態(tài)生成蒂萎。
- Cglib是可以代理沒有實現(xiàn)接口的類秆吵,cglib是針對類來實現(xiàn)代理的,他的原理是對指定的目標類生成一個子類五慈,并覆蓋其中方法實現(xiàn)增強纳寂,所以不能對final修飾的類進行代理。底層采用ASM實現(xiàn)泻拦。
原理:AOP是面向切面編程毙芜,是通過動態(tài)代理(jdk動態(tài)代理)的方式為程序添加統(tǒng)一功能,集中解決一些公共問題争拐。
AOP就是縱向的編程腋粥,如業(yè)務1和業(yè)務2都需要一個共同的操作,與其往每個業(yè)務中都添加同樣的代碼陆错,不如寫一遍代碼,讓兩個業(yè)務共同使用這段代碼金赦。在日常有訂單管理音瓷、商品管理、資金管理夹抗、庫存管理等業(yè)務绳慎,都會需要到類似日志記錄、事務控制漠烧、權(quán)限控制杏愤、性能統(tǒng)計、異常處理及事務處理等已脓。AOP把所有共有代碼全部抽取出來珊楼,放置到某個地方集中管理,然后在具體運行時度液,再由容器動態(tài)織入這些共有代碼厕宗。
優(yōu)點:
- 各個步驟之間的良好隔離性耦合性大大降低
- 源代碼無關性画舌,再擴展功能的同時不對源碼進行修改操作
主要是兩種,一種是JDK動態(tài)代理已慢,一種是Cglib代理曲聂。
兩者的區(qū)別:
1.JDK動態(tài)代理只能代理實現(xiàn)了接口的類,動態(tài)代理類的字節(jié)碼在程序運行時由Java反射機制動態(tài)生成佑惠。
2.Cglib是可以代理沒有實現(xiàn)接口的類朋腋,cglib是針對類來實現(xiàn)代理的,他的原理是對指定的目標類生成一個子類膜楷,并覆蓋其中方法實現(xiàn)增強旭咽,所以不能對final修飾的類進行代理。底層采用ASM實現(xiàn)把将。
原理:AOP是面向切面編程轻专,是通過動態(tài)代理(jdk動態(tài)代理)的方式為程序添加統(tǒng)一功能,集中解決一些公共問題察蹲。
AOP就是縱向的編程请垛,如業(yè)務1和業(yè)務2都需要一個共同的操作,與其往每個業(yè)務中都添加同樣的代碼洽议,不如寫一遍代碼宗收,讓兩個業(yè)務共同使用這段代碼。在日常有訂單管理亚兄、商品管理混稽、資金管理、庫存管理等業(yè)務审胚,都會需要到類似日志記錄匈勋、事務控制、權(quán)限控制膳叨、性能統(tǒng)計洽洁、異常處理及事務處理等。AOP把所有共有代碼全部抽取出來菲嘴,放置到某個地方集中管理饿自,然后在具體運行時,再由容器動態(tài)織入這些共有代碼龄坪。
優(yōu)點:1.各個步驟之間的良好隔離性耦合性大大降低
2.源代碼無關性昭雌,再擴展功能的同時不對源碼進行修改操作
JDK代理的是實現(xiàn)
JDK動態(tài)代理的實現(xiàn)是在運行時,根據(jù)一組接口定義健田,使用Proxy烛卧、InvocationHandler等工具類去生成一個代理類和代理類實例。
JDK動態(tài)代理的類關系模型和靜態(tài)代理看起來差不多妓局。也是需要一個或一組接口來定義行為規(guī)范唱星。需要一個代理類來實現(xiàn)接口雳旅。區(qū)別是沒有真實類,因為動態(tài)代理就是要解決在不知道真實類的情況下依然能夠使用代理模式的問題
public interface MyIntf {
void helloWorld();
}
第二步哎榴,編寫一個我們自己的調(diào)用處理類型豁,這個類需要實現(xiàn)InvocationHandler接口。
public class MyInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(method);
return null;
}
}
InvocationHandler接口只有一個待實現(xiàn)的invoke方法尚蝌。這個方法有三個參數(shù)迎变,proxy表示動態(tài)代理類實例,method表示調(diào)用的方法飘言,args表示調(diào)用方法的參數(shù)衣形。在實際應用中,invoke方法就是我們實現(xiàn)業(yè)務邏輯的入口姿鸿。這里我們的實現(xiàn)邏輯就一行代碼谆吴,打印當前調(diào)用的方法(在實際應用中這么做是沒有意義的,不過這里我們只想解釋JDK動態(tài)代理的原理苛预,所以越簡單越清晰)句狼。
第三步,直接使用Proxy提供的方法創(chuàng)建一個動態(tài)代理類實例热某。并調(diào)用代理類實例的helloWorld方法腻菇,檢測運行結(jié)果。
public class ProxyTest {
public static void main(String[] args) {
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
MyIntf proxyObj = (MyIntf)Proxy.newProxyInstance(MyIntf.class.getClassLoader(),new Class[]{MyIntf.class},new MyInvocationHandler());
proxyObj.helloWorld();
}
}
第三行代碼是設置系統(tǒng)屬性昔馋,把生成的代理類寫入到文件筹吐。這里再強調(diào)一下,JDK動態(tài)代理技術是在運行時直接生成類的字節(jié)碼秘遏,并載入到虛擬機執(zhí)行的丘薛。這里不存在class文件的,所以我們通過設置系統(tǒng)屬性垄提,把生成的字節(jié)碼保存到文件榔袋,用于后面進一步分析周拐。
第四行代碼就是調(diào)用Proxy.newProxyInstance方法創(chuàng)建一個動態(tài)代理類實例铡俐,這個方法需要傳入三個參數(shù),第一個參數(shù)是類加載器妥粟,用于加載這個代理類审丘。第二個參數(shù)是Class數(shù)組,里面存放的是待實現(xiàn)的接口信息勾给。第三個參數(shù)是InvocationHandler實例滩报。
第五行調(diào)用代理類的helloWorld方法锅知,運行結(jié)果:
public abstract void com.tuniu.distribute.openapi.common.annotation.MyIntf.helloWorld()
分析運行結(jié)果,就可以發(fā)現(xiàn)脓钾,方法的最終調(diào)用是分派到了MyInvocationHandler.invoke方法售睹,打印出了調(diào)用的方法信息。
3. Spring中IOC的作用與原理可训?對象創(chuàng)建的過程昌妹。
IOC--Inversion of Control控制反轉(zhuǎn)。當某個角色需要另外一個角色協(xié)助的時候握截,在傳統(tǒng)的程序設計過程中飞崖,通常由調(diào)用者來創(chuàng)建被調(diào)用者的實例對象。但在spring中創(chuàng)建被調(diào)用者的工作不再由調(diào)用者來完成谨胞,因此稱為控制反轉(zhuǎn)固歪。創(chuàng)建被調(diào)用者的工作由spring來完成,然后注入調(diào)用者 直接使用胯努。
IOC容器:就是具有依賴注入功能的容器牢裳,是可以創(chuàng)建對象的容器, BeanFactory是IoC容器的核心接口康聂。它的職責包括:實例化贰健、定位、配置應用程序中的對象及建立這些對象間的依賴恬汁,通常new一個實例伶椿,控制權(quán)由程序員控制,而"控制反轉(zhuǎn)"是指new實例工作不由程序員來做而是交給Spring容器來做氓侧。 Spring為我們提供了許多易用的BeanFactory實現(xiàn)脊另,XmlBeanFactory就是最常用的一個。該實現(xiàn)將以XML方式描述組成應用的對象以及對象間的依賴關系约巷。XmlBeanFactory類將持有此XML配置元數(shù)據(jù)偎痛,并用它來構(gòu)建一個完全可配置的系統(tǒng)或應用
DI(依賴注入Dependency injection) :在容器創(chuàng)建對象后,處理對象的依賴關系独郎。
依賴注入spring的注入方式:
- set注入方式
- 靜態(tài)工廠注入方式
- 構(gòu)造方法注入方式
- 基于注解的方式
- 依賴注入的三種方式:(1)接口注入(2)Construct注入(3)Setter注入
4.spring有兩種代理方式:
若目標對象實現(xiàn)了若干接口踩麦,spring使用JDK的java.lang.reflect.Proxy類代理。
優(yōu)點:因為有接口氓癌,所以使系統(tǒng)更加松耦合
缺點:為每一個目標類創(chuàng)建接口若目標對象沒有實現(xiàn)任何接口谓谦,spring使用CGLIB庫生成目標對象的子類。
優(yōu)點:因為代理類與目標類是繼承關系贪婉,所以不需要有接口的存在反粥。
缺點:因為沒有使用接口,所以系統(tǒng)的耦合性沒有使用JDK的動態(tài)代理好。
代理的共有優(yōu)點:業(yè)務類只需要關注業(yè)務邏輯本身才顿,保證了業(yè)務類的重用性
5.spring中的核心類有那些莫湘,各有什么作用?
BeanFactory:產(chǎn)生一個新的實例郑气,可以實現(xiàn)單例模式
BeanWrapper:提供統(tǒng)一的get及set方法
ApplicationContext:提供框架的實現(xiàn)幅垮,包括BeanFactory的所有功能
6.什么是IOC,什么又是DI尾组,他們有什么區(qū)別军洼?
依賴注入DI是一個程序設計模式和架構(gòu)模型, 一些時候也稱作控制反轉(zhuǎn)演怎,盡管在技術上來講匕争,依賴注入是一個IOC的特殊實現(xiàn),依賴注入是指一個對象應用另外一個對象來提供一個特殊的能力爷耀,例如:把一個 數(shù)據(jù)庫連接已參數(shù)的形式傳到一個對象的結(jié)構(gòu)方法里面而不是在那個對象內(nèi)部自行創(chuàng)建一個連接甘桑。控制反轉(zhuǎn)和依賴注入的基本思想就是把類的依賴從類內(nèi)部轉(zhuǎn)化到外 部以減少依賴
應用控制反轉(zhuǎn)歹叮,對象在被創(chuàng)建的時候跑杭,由一個調(diào)控系統(tǒng)內(nèi)所有對象的外界實體,將其所依賴的對象的引用咆耿,傳遞給它德谅。也可以說,依賴被注入到對象中萨螺。所 以窄做,控制反轉(zhuǎn)是,關于一個對象如何獲取他所依賴的對象的引用慰技,這個責任的反轉(zhuǎn)椭盏。
7.Spring常見創(chuàng)建對象的注解?
@component
除了上述提到的 @Component注解外吻商,Spring中還提供了@Component的3個衍生注解掏颊,其功能就目前來說是一致的,均是為了創(chuàng)建對象艾帐。
@Controller :WEB層
@Service :業(yè)務層
@Repository :持久層
@Service
@Service是一個注解乌叶,告訴spring創(chuàng)建一個實現(xiàn)類的實例,就是不用再spring里配置bean
@Configuration和@Bean
@Configuration可理解為用spring的時候xml里面的<beans>標簽
@Bean可理解為用spring的時候xml里面的<bean>標簽
@EnableConfigurationProperties
作用是@ConfigurationProperties注解生效
@ConfigurationProperties
主要用來把properties配置文件轉(zhuǎn)化為bean來使用的柒爸,就是綁定application.properties中的屬性
就是綁定application.properties中的屬性
@ImportResource
引入spring配置文件.xml
@Autowired
它可以對類成員變量准浴、方法及構(gòu)造函數(shù)進行標注,完成自動裝配的工作揍鸟。 通過 @Autowired的使用來消除 set 兄裂,get方法。
@ConditionalOnBean(僅僅在當前上下文中存在某個對象時阳藻,才會實例化一個Bean)
@ConditionalOnClass(某個class位于類路徑上晰奖,才會實例化一個Bean)
@ConditionalOnExpression(當表達式為true的時候,才會實例化一個Bean)
@ConditionalOnMissingBean(僅僅在當前上下文中不存在某個對象時腥泥,才會實例化一個Bean)
@ConditionalOnMissingClass(某個class類路徑上不存在的時候匾南,才會實例化一個Bean)
@ConditionalOnNotWebApplication(不是web應用)
8.Spring的優(yōu)點?
1.降低了組件之間的耦合性 蛔外,實現(xiàn)了軟件各層之間的解耦
2.可以使用容易提供的眾多服務蛆楞,如事務管理,消息服務等
3.容器提供單例模式支持
4.容器提供了AOP技術夹厌,利用它很容易實現(xiàn)如權(quán)限攔截豹爹,運行期監(jiān)控等功能
5.容器提供了眾多的輔助類,能加快應用的開發(fā)
6.spring對于主流的應用框架提供了集成支持矛纹,如hibernate臂聋,JPA,Struts等
7.spring屬于低侵入式設計或南,代碼的污染極低
8.獨立于各種應用服務器
9.spring的DI機制降低了業(yè)務對象替換的復雜性
10.Spring的高度開放性孩等,并不強制應用完全依賴于Spring,開發(fā)者可以自由選擇spring 的部分或全部
9.Spring Bean的作用域之間有什么區(qū)別采够?
Spring容器中的bean可以分為5個范圍肄方。所有范圍的名稱都是自說明的,但是為了避免混淆蹬癌,還是讓我們來解釋一下:
singleton:這種bean范圍是默認的权她,這種范圍確保不管接受到多少個請求,每個容器中只有一個bean的實例逝薪,單例的模式由bean factory自身來維護伴奥。
prototype:原形范圍與單例范圍相反,為每一個bean請求提供一個實例翼闽。
request:在請求bean范圍內(nèi)會每一個來自客戶端的網(wǎng)絡請求創(chuàng)建一個實例拾徙,在請求完成以后,bean會失效并被垃圾回收器回收感局。
Session:與請求范圍類似尼啡,確保每個session中有一個bean的實例,在session過期后询微,bean會隨之失效崖瞭。
global-session:global-session和Portlet應用相關。當你的應用部署在Portlet容器中工作時撑毛,它包含很多portlet书聚。如果你想要聲明讓所有的portlet共用全局的存儲變量的話,那么這全局變量需要存儲在global-session中。
全局作用域與Servlet中的session作用域效果相同雌续。
10.Spring事務
Spring事務其實就是Spring AOP,底層創(chuàng)建動態(tài)代理對象斩个,在代碼的開頭結(jié)尾封裝了開啟事務和事務回滾操作
事務屬性這個概念,事務屬性通常由事務的傳播行為驯杜,事務的隔離級別受啥,事務的超時值和事務只讀標志組成
什么是事務*
事務是訪問數(shù)據(jù)庫的一個操作序列,數(shù)據(jù)庫應用系統(tǒng)通過事務集來完成對數(shù)據(jù)庫的存取鸽心。事務的正確執(zhí)行使得數(shù)據(jù)庫從一種狀態(tài)轉(zhuǎn)換為另一種狀態(tài)滚局。
事務必須服從ISO/IEC所制定的ACID原則。ACID是原子性(atomicity)顽频、一致性(consistency)藤肢、隔離性(isolation)、持久性(durability)的縮寫糯景,這四種狀態(tài)的意思是:
1谤草、原子性
即不可分割,事務要么全部被執(zhí)行莺奸,要么全部不執(zhí)行丑孩。如果事務的所有子事務全部提交成功,則所有的數(shù)據(jù)庫操作被提交灭贷,數(shù)據(jù)庫狀態(tài)發(fā)生變化温学;如果有子事務失敗,則其他子事務的數(shù)據(jù)庫操作被回滾甚疟,即數(shù)據(jù)庫回到事務執(zhí)行前的狀態(tài)仗岖,不會發(fā)生狀態(tài)轉(zhuǎn)換
2、一致性
事務的執(zhí)行使得數(shù)據(jù)庫從一種正確狀態(tài)轉(zhuǎn)換成另外一種正確狀態(tài)
3览妖、隔離性
在事務正確提交之前轧拄,不允許把事務對該數(shù)據(jù)的改變提供給任何其他事務,即在事務正確提交之前讽膏,它可能的結(jié)果不應該顯示給其他事務
4檩电、持久性
事務正確提交之后,其結(jié)果將永遠保存在數(shù)據(jù)庫之中府树,即使在事務提交之后有了其他故障俐末,事務的處理結(jié)果也會得到保存
事務的作用
事務管理對于企業(yè)級應用而言至關重要,它保證了用戶的每一次操作都是可靠的奄侠,即便出現(xiàn)了異常的訪問情況卓箫,也不至于破壞后臺數(shù)據(jù)的完整性嗜憔。就像銀行的自動提款機ATM睹酌,通常ATM都可以正常為客戶服務,但是也難免遇到操作過程中及其突然出故障的情況湃累,此時食呻,事務就必須確保出故障前對賬戶的操作不生效亲轨,就像用戶剛才完全沒有使用過ATM機一樣醇坝,以保證用戶和銀行的利益都不受損失调限。
并發(fā)下事務會產(chǎn)生的問題
舉個例子,事務A和事務B操縱的是同一個資源坠非,事務A有若干個子事務,事務B也有若干個子事務果正,事務A和事務B在高并發(fā)的情況下炎码,會出現(xiàn)各種各樣的問題。"各種各樣的問題"秋泳,總結(jié)一下主要就是五種:第一類丟失更新潦闲、第二類丟失更新、臟讀迫皱、不可重復讀歉闰、幻讀。五種之中卓起,第一類丟失更新和敬、第二類丟失更新不重要,不講了戏阅,講一下臟讀昼弟、不可重復讀和幻讀。
1奕筐、臟讀
所謂臟讀舱痘,就是指事務A讀到了事務B還沒有提交的數(shù)據(jù),比如銀行取錢离赫,事務A開啟事務芭逝,此時切換到事務B,事務B開啟事務-->取走100元渊胸,此時切換回事務A旬盯,事務A讀取的肯定是數(shù)據(jù)庫里面的原始數(shù)據(jù),因為事務B取走了100塊錢翎猛,并沒有提交瓢捉,數(shù)據(jù)庫里面的賬務余額肯定還是原始余額,這就是臟讀办成。
2泡态、不可重復讀
所謂不可重復讀,就是指在一個事務里面讀取了兩次某個數(shù)據(jù)迂卢,讀出來的數(shù)據(jù)不一致某弦。還是以銀行取錢為例桐汤,事務A開啟事務-->查出銀行卡余額為1000元,此時切換到事務B事務B開啟事務-->事務B取走100元-->提交靶壮,數(shù)據(jù)庫里面余額變?yōu)?00元怔毛,此時切換回事務A,事務A再查一次查出賬戶余額為900元腾降,這樣對事務A而言拣度,在同一個事務內(nèi)兩次讀取賬戶余額數(shù)據(jù)不一致,這就是不可重復讀螃壤。
3抗果、幻讀
所謂幻讀,就是指在一個事務里面的操作中發(fā)現(xiàn)了未被操作的數(shù)據(jù)奸晴。比如學生信息冤馏,事務A開啟事務-->修改所有學生當天簽到狀況為false,此時切換到事務B寄啼,事務B開啟事務-->事務B插入了一條學生數(shù)據(jù)逮光,此時切換回事務A,事務A提交的時候發(fā)現(xiàn)了一條自己沒有修改過的數(shù)據(jù)墩划,這就是幻讀涕刚,就好像發(fā)生了幻覺一樣∫野铮幻讀出現(xiàn)的前提是并發(fā)的事務中有事務發(fā)生了插入副女、刪除操作。
事務隔離級別
事務隔離級別蚣旱,就是為了解決上面幾種問題而誕生的碑幅。為什么要有事務隔離級別,因為事務隔離級別越高塞绿,在并發(fā)下會產(chǎn)生的問題就越少沟涨,但同時付出的性能消耗也將越大,因此很多時候必須在并發(fā)性和性能之間做一個權(quán)衡异吻。所以設立了幾種事務隔離級別裹赴,以便讓不同的項目可以根據(jù)自己項目的并發(fā)情況選擇合適的事務隔離級別,對于在事務隔離級別之外會產(chǎn)生的并發(fā)問題诀浪,在代碼中做補償棋返。
事務隔離級別有4種,但是像Spring會提供給用戶5種雷猪,來看一下:
1睛竣、DEFAULT(default)
默認隔離級別,每種數(shù)據(jù)庫支持的事務隔離級別不一樣求摇,如果Spring配置事務時將isolation設置為這個值的話射沟,那么將使用底層數(shù)據(jù)庫的默認事務隔離級別殊者。順便說一句,如果使用的MySQL验夯,可以使用"select @@tx_isolation"來查看默認的事務隔離級別
2猖吴、READ_UNCOMMITTED(read_uncommitted)
讀未提交,即能夠讀取到?jīng)]有被提交的數(shù)據(jù)挥转,所以很明顯這個級別的隔離機制無法解決臟讀海蔽、不可重復讀、幻讀中的任何一種绑谣,因此很少使用
3党窜、READ_COMMITED(read_commited)
讀已提交,即能夠讀到那些已經(jīng)提交的數(shù)據(jù)域仇,自然能夠防止臟讀刑然,但是無法限制不可重復讀和幻讀
4寺擂、REPEATABLE_READ(repeatable)
重復讀取暇务,即在數(shù)據(jù)讀出來之后加鎖,類似"select * from XXX for update"怔软,明確數(shù)據(jù)讀取出來就是為了更新用的垦细,所以要加一把鎖,防止別人修改它挡逼。REPEATABLE_READ的意思也類似括改,讀取了一條數(shù)據(jù),這個事務不結(jié)束家坎,別的事務就不可以改這條記錄嘱能,這樣就解決了臟讀、不可重復讀的問題虱疏,但是幻讀的問題還是無法解決
5惹骂、SERLALIZABLE(serlalizable)
串行化(序列化 ),最高的事務隔離級別做瞪,不管多少事務对粪,挨個運行完一個事務的所有子事務之后才可以執(zhí)行另外一個事務里面的所有子事務,這樣就解決了臟讀装蓬、不可重復讀和幻讀的問題了
10.Spring管理事務有幾種方式著拭?
有兩種方式:
1、編程式事務牍帚,在代碼中硬編碼儡遮。(不推薦使用)
2、聲明式事務暗赶,在配置文件中配置(推薦使用)
聲明式事務又分為兩種:
a峦萎、基于XML的聲明式事務
b屡久、基于注解的聲明式事務
11.Springmvc的優(yōu)點
1.它是基于組件技術的.全部的應用對象,無論控制器和視圖,還是業(yè)務對象之類的都是 java組件.并且和Spring提供的其他基礎結(jié)構(gòu)緊密集成.
2.不依賴于Servlet API(目標雖是如此,但是在實現(xiàn)的時候確實是依賴于Servlet的)
- 可以任意使用各種視圖技術,而不僅僅局限于JSP
4 . 支持各種請求資源的映射策略
5 .它應是易于擴展的
12.SpringBean的生命周期
Spring MVC 的簡單原理圖如下:
SpringMVC 工作原理(重要)
簡單來說:
客戶端發(fā)送請求-> 前端控制器 DispatcherServlet 接受客戶端請求 -> 找到處理器映射 HandlerMapping 解析請求對應的 Handler-> HandlerAdapter 會根據(jù) Handler 來調(diào)用真正的處理器開處理請求,并處理相應的業(yè)務邏輯 -> 處理器返回一個模型視圖 ModelAndView -> 視圖解析器進行解析 -> 返回一個視圖對象->前端控制器 DispatcherServlet 渲染數(shù)據(jù)(Moder)->將得到視圖對象返回給用戶
流程說明(重要):
(1)客戶端(瀏覽器)發(fā)送請求爱榔,直接請求到 DispatcherServlet被环。
(2)DispatcherServlet 根據(jù)請求信息調(diào)用 HandlerMapping,解析請求對應的 Handler详幽。
(3)解析到對應的 Handler(也就是我們平常說的 Controller 控制器)后筛欢,開始由 HandlerAdapter 適配器處理。
(4)HandlerAdapter 會根據(jù) Handler 來調(diào)用真正的處理器開處理請求唇聘,并處理相應的業(yè)務邏輯版姑。
(5)處理器處理完業(yè)務后,會返回一個 ModelAndView 對象迟郎,Model 是返回的數(shù)據(jù)對象剥险,View 是個邏輯上的 View。
(6)ViewResolver 會根據(jù)邏輯 View 查找實際的 View宪肖。
(7)DispaterServlet 把返回的 Model 傳給 View(視圖渲染)表制。
(8)把 View 返回給請求者(瀏覽器)