1、Spring優(yōu)點(diǎn):
- 低侵入式的設(shè)計,代碼污染度低弓柱;
- 獨(dú)立于各種應(yīng)用服務(wù)器,基于Spring框架的應(yīng)用真正實現(xiàn)了write onece侧但、run anywhere矢空;
- Spring的IOC容器降低了業(yè)務(wù)對象替換的復(fù)雜度,提高了組件間的解耦禀横;
- Spring的AOP將一些通用的功能任務(wù)和安全屁药、事物、日志等進(jìn)行集中管理柏锄;
-
Spring的ORM(對象關(guān)系映射酿箭,虛擬數(shù)據(jù)庫)和DAO(面向?qū)ο蟮臄?shù)據(jù)庫接口)提供了與第三方框架的整合,方便訪問數(shù)據(jù)庫趾娃;image.png
2缭嫡、Spring核心機(jī)制:
-
管理Bean 程序主要通過Spring容器來訪問Bean,ApplicationContext是Spring容器最常用的接口抬闷,該接口有兩個實現(xiàn)類:ClassPathXMLApplicationContext從類加載路徑下搜索配置文件妇蛀;FileSystemXMLApplicationContext從文件系統(tǒng)的相對路徑下搜索配置文件;image.png
-
依賴注入 當(dāng)某個Java對象調(diào)用另一個Java對象時,傳統(tǒng)方法有兩種:
(1)調(diào)用者主動創(chuàng)建被依賴的對象评架,然后再調(diào)用被依賴對象的方法眷茁;
(2)簡單工廠模式:調(diào)用者先找到被依賴對象的工廠,然后主動通過工廠去獲取被依賴的對象纵诞。
使用Spring后蔼卡,調(diào)用者無需主動獲取被依賴的對象,調(diào)用者只需要被動的接受Spring 容器為調(diào)用者的成員變量賦值挣磨,由原來的主動獲取變成被動的賦值所以也叫控制反轉(zhuǎn)。從Spring容器來看荤懂,Spring容器負(fù)責(zé)將被依賴的對象賦值給調(diào)用者的成員變量茁裙,相當(dāng)于為調(diào)用者注入它所需要的實例,因此叫做依賴注入节仿。依賴注入是一種優(yōu)秀的解耦方式晤锥,可以讓Bean以配置文件組織在一起而不是以硬編碼的方式。注入方式有設(shè)值注入和構(gòu)造注入廊宪,設(shè)值注入指IOC容器通過成員變量以setter的方式注入被依賴的對象矾瘾;構(gòu)造注入指利用構(gòu)造器來設(shè)置依賴關(guān)系的方式,就是驅(qū)動Spring在底層以反射方式執(zhí)行帶指定參數(shù)的構(gòu)造器箭启,當(dāng)執(zhí)行帶參數(shù)得構(gòu)造器時壕翩,就可以利用構(gòu)造器參數(shù)對成員變量執(zhí)行初始化。image.png
3傅寡、SpringMVC的流程:
image.png
- 用戶發(fā)送請求至前端控制器DispatcherServelt放妈;
- 前端控制器收到請求調(diào)用處理器映射器HandlerMapping;
- 處理器映射器找到具體的處理器荐操,生成處理器對象及處理器攔截器一并返回給前端控制器芜抒;
- 前端控制器調(diào)用處理器適配器HandlerAdapter;
- 處理器適配器調(diào)用具體的處理器(如Controller,也叫后端處理器);
- Controller執(zhí)行完成返回ModelAndView;
- 處理器適配器將controller執(zhí)行結(jié)果ModelAndView返回給前端控制器;
- 前端控制器將ModelAndView傳給ViewReslover視圖解析器托启;
- ViewReslover解析后返回具體View;
- DispatcherServelt根據(jù)View進(jìn)行渲染視圖(即將模型數(shù)據(jù)填充至視圖中)宅倒;
- DispatcherServelt響應(yīng)用戶。
4屯耸、IOC
4.1 概念
Spring 通過一個配置文件描述 Bean 及 Bean 之間的依賴關(guān)系拐迁,利用 Java 語言的反射功能實例化 Bean 并建立 Bean 之間的依賴關(guān)系。 Spring 的 IoC 容器在完成這些底層工作的基礎(chǔ)上疗绣,還提供了 Bean 實例緩存唠亚、生命周期管理、 Bean 實例代理持痰、事件發(fā)布灶搜、資源裝載等高級服務(wù)。
4.2 Spring容器高層視圖
Spring 啟動時讀取應(yīng)用程序提供的Bean配置信息,并在Spring容器中生成一份相應(yīng)的Bean配置注冊表割卖,然后根據(jù)這張注冊表實例化Bean前酿,裝配好Bean之間的依賴關(guān)系,為上層應(yīng)用提供準(zhǔn)備就緒的運(yùn)行環(huán)境鹏溯。其中Bean緩存池為HashMap實現(xiàn)4.3 Spring 依賴注入四種方式
- 構(gòu)造器注入
/*帶參數(shù)罢维,方便利用構(gòu)造器進(jìn)行注入*/
public CatDaoImpl(String message){
this. message = message;
}
<bean id="CatDaoImpl" class="com.CatDaoImpl">
<constructor-arg value=" message "></constructor-arg>
</bean>
- setter方法注入
public class Id {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
<bean id="id" class="com.id "> <property name="id" value="123"></property> </bean>
- 靜態(tài)工廠注入
public class DaoFactory { //靜態(tài)工廠
public static final FactoryDao getStaticFactoryDaoImpl(){
return new StaticFacotryDaoImpl();
}
}
public class SpringAction {
private FactoryDao staticFactoryDao; //注入對象
//注入對象的set方法
public void setStaticFactoryDao(FactoryDao staticFactoryDao) {
this.staticFactoryDao = staticFactoryDao;
}
}
//factory-method="getStaticFactoryDaoImpl"指定調(diào)用哪個工廠方法
<bean name="springAction" class=" SpringAction" >
<!--使用靜態(tài)工廠的方法注入對象,對應(yīng)下面的配置文件-->
<property name="staticFactoryDao" ref="staticFactoryDao"></property>
</bean>
<!--此處獲取對象的方式是從工廠類中獲取靜態(tài)方法-->
<bean name="staticFactoryDao" class="DaoFactory"
factory-method="getStaticFactoryDaoImpl"></bean>
- 實例工廠
public class DaoFactory { //實例工廠
public FactoryDao getFactoryDaoImpl(){
return new FactoryDaoImpl();
}
}
public class SpringAction {
private FactoryDao factoryDao; //注入對象
public void setFactoryDao(FactoryDao factoryDao) {
this.factoryDao = factoryDao;
}
}
<bean name="springAction" class="SpringAction">
<!--使用實例工廠的方法注入對象,對應(yīng)下面的配置文件-->
<property name="factoryDao" ref="factoryDao"></property>
</bean>
<!--此處獲取對象的方式是從工廠類中獲取實例方法-->
<bean name="daoFactory" class="com.DaoFactory"></bean>
<bean name="factoryDao" factory-bean="daoFactory"
factory-method="getFactoryDaoImpl"></bean>
4.4 5種不同方式的自動裝配
Spring裝配包括手動裝配和自動裝配,手動裝配是有基于xml裝配丙挽、構(gòu)造方法肺孵、setter方法等
自動裝配有五種自動裝配的方式,可以用來指導(dǎo)Spring容器用自動裝配方式來進(jìn)行依賴注入颜阐。
- no:默認(rèn)的方式是不進(jìn)行自動裝配平窘,通過顯式設(shè)置ref 屬性來進(jìn)行裝配。
- byName:通過參數(shù)名 自動裝配凳怨,Spring容器在配置文件中發(fā)現(xiàn)bean的autowire屬性被設(shè)置成byname瑰艘,之后容器試圖匹配、裝配和該bean的屬性具有相同名字的bean肤舞。
- byType:通過參數(shù)類型自動裝配紫新,Spring容器在配置文件中發(fā)現(xiàn)bean的autowire屬性被設(shè)置成byType,之后容器試圖匹配李剖、裝配和該bean的屬性具有相同類型的bean芒率。如果有多個bean符合條件,則拋出錯誤篙顺。
- constructor:這個方式類似于byType敲董, 但是要提供給構(gòu)造器參數(shù),如果沒有確定的帶參數(shù)的構(gòu)造器參數(shù)類型慰安,將會拋出異常腋寨。
- autodetect:首先嘗試使用constructor來自動裝配,如果無法工作化焕,則使用byType方式萄窜。
5、AOP
概念:aop是建立在java的反射基礎(chǔ)上撒桨,將程序種公共的部分提取出來做成切面類查刻,便于代碼的復(fù)用,一旦需要改該功能的需求發(fā)生變化只需要改該代碼即可凤类。AOP的實現(xiàn)方式主要有JDK動態(tài)代理和CGLIB穗泵。
意義:增強(qiáng)類的功能(在目標(biāo)對象的方法執(zhí)行之間和執(zhí)行之后);各個步驟之間的良好隔離性耦合性大大降低谜疤;源代碼無關(guān)性佃延,再拓展功能的同時不對源碼進(jìn)行修改操作现诀。
原理:
- 靜態(tài)代理:AspectJ,AOP框架會在編譯階段將AspectJ織入Java的字節(jié)碼中履肃;AspectJ是靜態(tài)代理的增強(qiáng)仔沿,所謂的靜態(tài)代理就是AOP框架會在編譯階段生成AOP代理類,在程序運(yùn)行之前尺棋,代理類的.class文件就已經(jīng)生成封锉,因此也稱為編譯時增強(qiáng)
- 動態(tài)代理:AOP不會去修改字節(jié)碼,而是在內(nèi)存中臨時為方法生成一個AOP對象膘螟,這個對象包含了目標(biāo)對象的全部方法成福,并在特定的切點(diǎn)去做了增強(qiáng)處理,并回調(diào)原對象方法荆残。主要有JDK動態(tài)代理(接口)和CGLIB動態(tài)代理(繼承)奴艾,JDK動態(tài)代理主要通過反射來接受被處理的對象,并且要求被代理的對象必須實現(xiàn)一個接口脊阴。
JDK動態(tài)接口代理
JDK動態(tài)代理主要涉及到j(luò)ava.lang.reflect包中的兩個類:Proxy和InvocationHandler。InvocationHandler是一個接口蚯瞧,通過實現(xiàn)該接口定義橫切邏輯嘿期,并通過反射機(jī)制調(diào)用目標(biāo)類的代碼,動態(tài)將橫切邏輯和業(yè)務(wù)邏輯編制在一起埋合。Proxy利用InvocationHandler動態(tài)創(chuàng)建一個符合某一接口的實例备徐,生成目標(biāo)類的代理對象。
CGLib動態(tài)代理
CGLib全稱為Code Generation Library甚颂,是一個強(qiáng)大的高性能蜜猾,高質(zhì)量的代碼生成類庫,可以在運(yùn)行期擴(kuò)展Java類與實現(xiàn)Java接口振诬,CGLib封裝了asm蹭睡,可以再運(yùn)行期動態(tài)生成新的class。和JDK動態(tài)代理相比較:JDK創(chuàng)建代理有一個限制赶么,就是只能為接口創(chuàng)建代理實例肩豁,而對于沒有通過接口定義業(yè)務(wù)方法的類,則可以通過CGLib創(chuàng)建動態(tài)代理辫呻。
6清钥、SpringBean的作用域
- Singleton:IOC容器僅創(chuàng)建一個Bean實例,IOC容器每次返回的都是同一個Bean實例默認(rèn)的作用域放闺;
- prototype:IOC容器可以創(chuàng)建多個Bean實例祟昭,每次返回的都是一個新的實例;
- request:每次Http請求都會創(chuàng)建一個新的實例怖侦;
- session:同一個session共享一個Bean實例篡悟;
- global-session:所有的session共享一個Bean實例谜叹;
7、Bean的生命周期:
image.png
-
實例化
實例化一個Bean恰力,也就是我們常說的new叉谜; -
IOC依賴注入
按照Spring上下文對實例化的Bean進(jìn)行配置; -
setBeanName實現(xiàn)
如果這個Bean已經(jīng)實現(xiàn)了BeanNameAware接口踩萎,會調(diào)用它實現(xiàn)的setBeanName(String)方法停局,此處傳遞的就是Spring配置文件中Bean的id值; -
BeanFactoryAware實現(xiàn)
如果這個Bean已經(jīng)實現(xiàn)了BeanFactoryAware接口香府,會調(diào)用它實現(xiàn)的setBeanFactory(setBeanFactory(BeanFactory)傳遞的是Spring工廠自身(可以用這個方式來獲取其它Bean董栽,只需在Spring配置文件中配置一個普通的Bean就可以); -
ApplicationContextAware實現(xiàn)
如果這個Bean已經(jīng)實現(xiàn)了ApplicationContextAware接口企孩,會調(diào)用setApplicationContext(ApplicationContext)方法锭碳,傳入Spring上下文(同樣這個方式也可以實現(xiàn)步驟4的內(nèi)容,但比4更好勿璃,因為ApplicationContext是BeanFactory的子接口擒抛,有更多的實現(xiàn)方法); -
postProcessBeforeInitialization接口實現(xiàn)-初始化預(yù)處理
如果這個Bean關(guān)聯(lián)了BeanPostProcessor接口补疑,將會調(diào)用postProcessBeforeInitialization(Object obj, String s)方法歧沪,BeanPostProcessor經(jīng)常被用作是Bean內(nèi)容的更改,并且由于這個是在Bean初始化結(jié)束時調(diào)用那個的方法莲组,也可以被應(yīng)用于內(nèi)存或緩存技術(shù)诊胞; -
init-method
如果Bean在Spring配置文件中配置了init-method屬性會自動調(diào)用其配置的初始化方法; -
postProcessAfterInitialization
如果這個Bean關(guān)聯(lián)了BeanPostProcessor接口锹杈,將會調(diào)用postProcessAfterInitialization(Object obj, String s)方法撵孤、;
注:以上工作完成以后就可以應(yīng)用這個Bean了竭望,那這個Bean是一個Singleton的邪码,所以一般情況下我們調(diào)用同一個id的Bean會是在內(nèi)容地址相同的實例,當(dāng)然在Spring配置文件中也可以配置非Singleton咬清,這里我們不做贅述霞扬。 -
Destroy過期自動清理階段
當(dāng)Bean不再需要時,會經(jīng)過清理階段枫振,如果Bean實現(xiàn)了DisposableBean這個接口喻圃,會調(diào)用那個其實現(xiàn)的destroy()方法; -
destroy-method自配置清理
最后粪滤,如果這個Bean的Spring配置中配置了destroy-method屬性斧拍,會自動調(diào)用其配置的銷毀方法。
一旦把一個bean納入到Spring IoC容器之中杖小,這個bean的生命周期就會交由容器進(jìn)行管理肆汹,一般擔(dān)當(dāng)管理者角色的是BeanFactory或ApplicationContext愚墓。
8、Spring處理循環(huán)依賴參考
發(fā)生循環(huán)依賴的三種方式:
- 構(gòu)造器參數(shù)循環(huán)依賴(無法解決)
- setter方式單例昂勉,默認(rèn)方式
- setter方式原型浪册,prototype(無法解決)
Spring bean初始化的循環(huán)依賴只能解決單例模式的set方式,spring通過三級緩存來解決單例模式循環(huán)依賴岗照。
//singletonObjects指單例對象的cache
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
//單例對象工廠的cache
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
//提前曝光的單例對象的cache
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
- Spring Bean的的創(chuàng)建包含兩部分:當(dāng)前對象的實例化和對象屬性的實例化村象。Spring中對象的實例化是通過反射來實現(xiàn)的,而對象的屬性則是在對象實例化后通過一定的方式來設(shè)置的攒至。
9厚者、過濾器和攔截器的區(qū)別
- 攔截器是基于java反射實現(xiàn)的,而過濾器是根據(jù)函數(shù)回調(diào)實現(xiàn)的迫吐;
- 攔截器不依賴servelt,過濾器依賴servelt熙宇;
- 攔截器只能對action請求起作用,過濾器可以對所有請求起作用圆裕;
- 攔截器可以訪問action上下文赊时、值祖秒、棧里的值,而過濾器不能訪問抬纸;
- 在action的生命周期內(nèi)阿趁,攔截器可以多次被調(diào)用,而過濾器只能在容器被初始化時被調(diào)用一次;
- 攔截器可以獲取IOC容器的各個Bean,過濾器不能纷铣。
10、Spring中用到的設(shè)計模式
- 簡單工廠:Spring中BeanFactory就是工廠模式的提現(xiàn),根據(jù)傳入一個唯一的標(biāo)識來獲得Bean對象;
- 工廠方法:實現(xiàn)了FactoryBean接口的bean是一類叫做factory的bean顿锰。其特點(diǎn)是胳赌,spring會在使用getBean()調(diào)用獲得該bean時熏版,會自動調(diào)用該bean的getObject()方法,所以返回的不是factory這個bean曲横,而是這個bean.getOjbect()方法的返回值。
- 單例模式:Spring依賴注入Bean實例默認(rèn)是單例的吭露。Spring中的單例模式提供了一個全局的訪問點(diǎn)BeanFactory,沒有從構(gòu)造器級別去控制實例,因為Spring管理的是任意的Bean。
- 適配器模式:SpringMVC中的HandlerAdatper根據(jù)Handler規(guī)則執(zhí)行不同的Handler秀仲。Spring定義了一個適配接口覆劈,使得每一種Controller有一種對應(yīng)的適配器實現(xiàn)類炮障,讓適配器代替controller執(zhí)行相應(yīng)的方法址貌。這樣在擴(kuò)展Controller時遍蟋,只需要增加一個適配器類就完成了SpringMVC的擴(kuò)展了螺男。
- 裝飾器模式:Spring中用到的包裝器模式在類名上有兩種表現(xiàn):一種是類名中含有Wrapper奢人,另一種是類名中含有Decorator。
- 代理模式:AOP底層抢野,就是動態(tài)代理模式的實現(xiàn)邓厕。切面在應(yīng)用運(yùn)行的時刻被織入引几。一般情況下,在織入切面時,AOP容器會為目標(biāo)對象創(chuàng)建動態(tài)的創(chuàng)建一個代理對象。SpringAOP就是以這種方式織入切面的听隐。
- 觀察者模式:spring的事件驅(qū)動模型使用的是 觀察者模式 咨跌,Spring中Observer模式常用的地方是listener的實現(xiàn)加酵。
- 策略模式:Spring框架的資源訪問Resource接口陋葡。該接口提供了更強(qiáng)的資源訪問能力岭粤,Spring 框架本身大量使用了 Resource 接口來訪問底層資源角塑。
- 模版方法模式:是模板方法模式和回調(diào)模式的結(jié)合淘讥,是Template Method不需要繼承的另一種實現(xiàn)方式圃伶。Spring幾乎所有的外接擴(kuò)展都采用這種模式。
11蒲列、JPA 原理
事務(wù)是計算機(jī)應(yīng)用中不可或缺的組件模型窒朋,它保證了用戶操作的原子性 ( Atomicity )、一致性 ( Consistency )嫉嘀、隔離性 ( Isolation ) 和持久性 ( Durabilily )炼邀。
11.1
-
本地事務(wù)
緊密依賴于底層資源管理器(例如數(shù)據(jù)庫連接 )魄揉,事務(wù)處理局限在當(dāng)前事務(wù)資源內(nèi)剪侮。此種事務(wù)處理方式不存在對應(yīng)用服務(wù)器的依賴,因而部署靈活卻無法支持多數(shù)據(jù)源的分布式事務(wù)。在數(shù)據(jù)庫連接中使用本地事務(wù)示例如下:
public void transferAccount() {
Connection conn = null;
Statement stmt = null;
try{
conn = getDataSource().getConnection();
// 將自動提交設(shè)置為 false瓣俯,若設(shè)置為 true 則數(shù)據(jù)庫將會把每一次數(shù)據(jù)更新認(rèn)定為一個事務(wù)并自動提交
conn.setAutoCommit(false);
stmt = conn.createStatement();
// 將 A 賬戶中的金額減少 500
stmt.execute("update t_account set amount = amount - 500 where account_id = 'A'");
// 將 B 賬戶中的金額增加 500
stmt.execute("update t_account set amount = amount + 500 where account_id = 'B'");
// 提交事務(wù)
conn.commit();
// 事務(wù)提交:轉(zhuǎn)賬的兩步操作同時成功
} catch(SQLException sqle){
// 發(fā)生異常杰标,回滾在本事務(wù)中的操做
conn.rollback();
// 事務(wù)回滾:轉(zhuǎn)賬的兩步操作完全撤銷
stmt.close();
conn.close();
}
}
-
分布式事務(wù)
Java 事務(wù)編程接口(JTA:Java Transaction API)和 Java 事務(wù)服務(wù) (JTS;Java Transaction Service) 為 J2EE 平臺提供了分布式事務(wù)服務(wù)彩匕。分布式事務(wù)(Distributed Transaction)包括事務(wù)管理器(Transaction Manager)和一個或多個支持 XA 協(xié)議的資源管理器 ( Resource Manager )腔剂。我們可以將資源管理器看做任意類型的持久化數(shù)據(jù)存儲;事務(wù)管理器承擔(dān)著所有事務(wù)參與單元的協(xié)調(diào)與控制驼仪。比較適合單塊應(yīng)用里掸犬,跨多個庫的分布式事務(wù)
public void transferAccount() {
UserTransaction userTx = null;
Connection connA = null; Statement stmtA = null;
Connection connB = null; Statement stmtB = null;
try{
// 獲得 Transaction 管理對象
userTx = (UserTransaction)getContext().lookup("java:comp/UserTransaction");
connA = getDataSourceA().getConnection();// 從數(shù)據(jù)庫 A 中取得數(shù)據(jù)庫連接
connB = getDataSourceB().getConnection();// 從數(shù)據(jù)庫 B 中取得數(shù)據(jù)庫連接
userTx.begin(); // 啟動事務(wù)
stmtA = connA.createStatement();// 將 A 賬戶中的金額減少 500
stmtA.execute("update t_account set amount = amount - 500 where account_id = 'A'");
// 將 B 賬戶中的金額增加 500
stmtB = connB.createStatement();
stmtB.execute("update t_account set amount = amount + 500 where account_id = 'B'");
userTx.commit();// 提交事務(wù)
// 事務(wù)提交:轉(zhuǎn)賬的兩步操作同時成功(數(shù)據(jù)庫 A 和數(shù)據(jù)庫 B 中的數(shù)據(jù)被同時更新)
} catch(SQLException sqle){
// 發(fā)生異常,回滾在本事務(wù)中的操縱
userTx.rollback();// 事務(wù)回滾:數(shù)據(jù)庫 A 和數(shù)據(jù)庫 B 中的數(shù)據(jù)更新被同時撤銷
} catch(Exception ne){ }
}
兩階段提交主要保證了分布式事務(wù)的原子性:即所有結(jié)點(diǎn)要么全做要么全不做绪爸,所謂的兩個階段是指:第一階段:準(zhǔn)備階段湾碎;第二階段:提交階段。
1)準(zhǔn)備階段
事務(wù)協(xié)調(diào)者(事務(wù)管理器)給每個參與者(資源管理器)發(fā)送Prepare消息奠货,每個參與者要么直接返回失敗(如權(quán)限驗證失敗)介褥,要么在本地執(zhí)行事務(wù),寫本地的redo和undo日志递惋,但不提交柔滔,到達(dá)一種“萬事俱備,只欠東風(fēng)”的狀態(tài)萍虽。
2)提交階段
如果協(xié)調(diào)者收到了參與者的失敗消息或者超時睛廊,直接給每個參與者發(fā)送回滾(Rollback)消息;否則杉编,發(fā)送提交(Commit)消息喉前;參與者根據(jù)協(xié)調(diào)者的指令執(zhí)行提交或者回滾操作,釋放所有事務(wù)處理過程中使用的鎖資源王财。(注意:必須在最后階段釋放鎖資源)
將提交分成兩階段進(jìn)行的目的很明確卵迂,就是盡可能晚地提交事務(wù),讓事務(wù)在提交前盡可能地完成所有能完成的工作绒净。
11.2事務(wù)的傳播性
一個開啟了事務(wù)的方法A见咒,調(diào)用了另一個開啟了事務(wù)的方法B,此時會出現(xiàn)什么情況挂疆?這就要看傳播行為的設(shè)置了改览。
- PROPAGATION_REQUIRED: 如果存在一個事務(wù),則支持當(dāng)前事務(wù)缤言。如果沒有事務(wù)則開啟一個新的事務(wù)宝当。
- PROPAGATION_SUPPORTS: 如果存在一個事務(wù),支持當(dāng)前事務(wù)胆萧。如果沒有事務(wù)庆揩,則非事務(wù)的執(zhí)行俐东。
- PROPAGATION_MANDATORY: 如果已經(jīng)存在一個事務(wù),支持當(dāng)前事務(wù)订晌。如果沒有一個活動的事務(wù)虏辫,則拋出異常。
- PROPAGATION_REQUIRES_NEW: 總是開啟一個新的事務(wù)锈拨。如果一個事務(wù)已經(jīng)存在砌庄,則將這個存在的事務(wù)掛起。
- PROPAGATION_NOT_SUPPORTED: 總是非事務(wù)地執(zhí)行奕枢,并掛起任何存在的事務(wù)娄昆。使用PROPAGATION_NOT_SUPPORTED,也需要使用JtaTransactionManager作為事務(wù)管理器。
- PROPAGATION_NEVER: 總是非事務(wù)地執(zhí)行缝彬,如果存在一個活動事務(wù)稿黄,則拋出異常。
- PROPAGATION_NESTED:如果一個活動的事務(wù)存在跌造,則運(yùn)行在一個嵌套的事務(wù)中. 如果沒有活動事務(wù), 則按TransactionDefinition.PROPAGATION_REQUIRED 屬性執(zhí)行杆怕。嵌套事務(wù)一個非常重要的概念就是內(nèi)層事務(wù)依賴于外層事務(wù)。外層事務(wù)失敗時壳贪,會回滾內(nèi)層事務(wù)所做的動作陵珍。而內(nèi)層事務(wù)操作失敗并不會引起外層事務(wù)的回滾。
12违施、Spring MVC接收參數(shù)的幾種方式(原文地址):
- 直接把表單的參數(shù)寫在Controller相應(yīng)的方法的形參中互纯;
- 通過HttpServeltRequest接收;
- 通過一個bean來接收磕蒲;
- 通過json數(shù)據(jù)來接收留潦;
13、JSP內(nèi)置對象
- request對象javax.servelt.http.HttpServletRequest,request對象代表客戶端的請求信息,主要用于接受通過HTTP協(xié)議傳送到服務(wù)器的數(shù)據(jù)杜秸。
- response對象javax.servlet.http.HttpServletResponse林螃,response代表的是對客戶端的響應(yīng)瞬矩,主要是將JSP容器處理過的對象傳回到客戶端。
- session對象javax.servlet.http.HttpSession,Session對象是一個JSP內(nèi)置對象,它在第一個JSP也main被裝載時自動創(chuàng)建十偶,完成會話期管理。從一個客戶打開瀏覽器并連接到服務(wù)器開始园细,到客戶關(guān)閉瀏覽器離開這個服務(wù)器結(jié)束惦积,被稱為一個會話。當(dāng)一個客戶訪問一個服務(wù)器時猛频,可能會在這個服務(wù)器的幾個頁面之間切換狮崩,服務(wù)器通過Session對象知道這是一個客戶蛛勉。
- application對象javax.servlet.ServletContext,application對象可將信息保存在服務(wù)器中厉亏,直到服務(wù)器關(guān)閉董习,否則application對象中保存的信息會在整個應(yīng)用中都有效烈和。與session對象相比爱只,application對象生命周期更長,類似于系統(tǒng)的全局變量招刹。
- out對象javax.servlet.jsp.jspWriter恬试,out對象用于在Web瀏覽器內(nèi)輸出信息,并且管理應(yīng)用服務(wù)器上的輸出緩存區(qū)疯暑。
- pageContext對象javax.servelt.jsp.PageContext训柴,pageContext對象的作用是取得任何范圍的參數(shù),通過它可以獲取JSP頁面的out妇拯、response幻馁、request、session越锈、application等對象在jsp頁面可以直接使用pageCOntext對象仗嗦。
- config對象javax.servlet.ServletConfig,config對象的主要作用是取得服務(wù)器的配置信息甘凭。
- cookie對象稀拐,cookie是web服務(wù)器保存在用戶硬盤上的一段文本。
- exception對象java.lang.Throwable丹弱,exception對象的作用是顯示異常信息德撬,只有在包含isErrorPage=”true”的頁面才可以使用,在一般的JSP頁面中使用該對象將無法編譯JSP文件躲胳。
14蜓洪、BeanFactory和ApplicationContext的區(qū)別
接口 BeanFactory 和 ApplicationContext 都是用來從容器中獲取 Spring beans( Spring 容器所管理的 Java 對象)。
- BeanFactory 接口
這是一個用來訪問 Spring 容器的 root 接口坯苹,要訪問 Spring 容器蝠咆,我們將使用 Spring 依賴注入功能,使用 BeanFactory 接口和它的子接口 特性:BeanFactory 的實現(xiàn)是使用懶加載的方式北滥,這意味著 beans 只有在我們通過getBean() 方法直接調(diào)用它們時才進(jìn)行實例化 實現(xiàn) BeanFactory 刚操。 - ApplicationContext 接口
ApplicationContext 是 Spring 應(yīng)用程序中的中央接口,用于向應(yīng)用程序提供配置信息 它繼承了 BeanFactory 接口再芋,所以 ApplicationContext 包含 BeanFactory 的所有功能以及更多功能菊霜。ApplicationContext在啟動的時候就把所有的Bean全部實例化了。它還可以為Bean配置lazy-init=true來讓Bean延遲實例化济赎;