談談你對Spring的理解
1.Spring是實現了工廠模式的工廠類(在這里有必要解釋清楚什么是工廠模式),這個類名為BeanFactory(實際上是一個接口),在程序中通常BeanFactory的子類ApplicationContext。Spring相當於一個大的工廠類,在其配置文件中通過
2. Spring提供了對IOC良好支持,IOC是一種編程思想,是一種架構藝術,利用這種思想可以很好地實現模塊之間的解耦,IOC也稱為DI(Depency Injection)。
3. Spring提供了對AOP技術的良好封裝, AOP稱為面向切面編程,就是系統中有很多各不相干的類的方法,在這些眾多方法中要加入某種系統功能的代碼,例如,加入日志,加入權限判斷,加入異常處理,這種應用稱為AOP。
實現AOP功能采用的是代理技術,客戶端程序不再調用目標,而調用代理類,代理類與目標類對外具有相同的方法聲明,有兩種方式可以實現相同的方法聲明,一是實現相同的接口,二是作為目標的子類。
在JDK中采用Proxy類產生動態代理的方式為某個接口生成實現類,如果要為某個類生成子類,則可以用CGLI B。在生成的代理類的方法中加入系統功能和調用目標類的相應方法,系統功能的代理以Advice對象進行提供,顯然要創建出代理對象,至少需要目標類和Advice類。spring提供了這種支持,只需要在spring配置文件中配置這兩個元素即可實現代理和aop功能。
使用Spring框架的好處是什么?
- 輕量:Spring 是輕量的,基本的版本大約2MB。
- 控制反轉:Spring通過控制反轉實現了松散耦合,對象們給出它們的依賴,而不是創建或查找依賴的對象們。
- 面向切面的編程(AOP):Spring支持面向切面的編程,並且把應用業務邏輯和系統服務分開。
- 容器:Spring 包含並管理應用中對象的生命周期和配置。
- MVC框架:Spring的WEB框架是個精心設計的框架,是Web框架的一個很好的替代品。
- 事務管理:Spring 提供一個持續的事務管理接口,可以擴展到上至本地事務下至全局事務(JTA)。
- 異常處理:Spring 提供方便的API把具體技術相關的異常(比如由JDBC,Hibernate or JDO拋出的)轉化為一致的unchecked 異常。
說一下Spring的核心模塊
- Spring Core【核心容器】:核心容器提供了Spring的基本功能。核心容器的核心功能是用IOC容器來管理類的依賴關系。
- Spring AOP【面向切面】:Spring的AOP模塊提供了面向切面編程的支持。SpringAOP采用的是純Java實現,采用基於代理的AOP實現方案,AOP代理由IOC容器負責生成、管理,依賴關系也一並由IOC容器管理。
- Spring ORM【對象實體映射】:提供了與多個第三方持久層框架的良好整合。
- Spring DAO【持久層模塊】: Spring進一步簡化DAO開發步驟,能以一致的方式使用數據庫訪問技術,用統一的方式調用事務管理,避免具體的實現侵入業務邏輯層的代碼中。
- Spring Context【應用上下文】:它是一個配置文件,為Spring提供上下文信息,提供了框架式的對象訪問方法。
- Spring Web【Web模塊】:提供了基礎的針對Web開發的集成特性。
- Spring MVC【MVC模塊】:提供了Web應用的MVC實現。Spring的MVC框架並不是僅僅提供一種傳統的實現,它提供了一種清晰的分離模型。
BeanFactory 和ApplicationContext的區別
BeanFactory和ApplicationContext都是接口,並且ApplicationContext是BeanFactory的子接口。
BeanFactory是Spring中最底層的接口,提供了最簡單的容器的功能,只提供了實例化對象和拿對象的功能。而ApplicationContext是Spring的一個更高級的容器,提供了更多的有用的功能。
ApplicationContext提供的額外的功能:國際化的功能、消息發送、響應機制、統一加載資源的功能、強大的事件機制、對Web應用的支持等等。
加載方式的區別:BeanFactory采用的是延遲加載的形式來注入Bean;ApplicationContext則相反的,它是在Ioc啟動時就一次性創建所有的Bean,好處是可以馬上發現Spring配置文件中的錯誤,壞處是造成浪費。
常見的 ApplicationContext 實現方式?
- ClassPathXmlApplicationContext:從classpath的XML配置文件中讀取上下文,並生成上下文定義。應用程序上下文從程序環境變量中取得。
ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”);
- FileSystemXmlApplicationContext : 由文件系統中的XML配置文件讀取上下文。
ApplicationContext context = new FileSystemXmlApplicationContext(“bean.xml”);
-
XmlWebApplicationContext: 由Web應用的XML文件讀取上下文。
-
讀取類定義上下文
ApplicationContext context = new AnnotationConfigApplicationContext(hello.class);
什么是控制反轉(IOC)?
- IOC不是一種技術,只是一種思想,一個重要的面向對象編程的法則,它能指導我們如何設計出松耦合、更優良的程序。
- 傳統的創建對象的方法是直接通過 new 關鍵字,而 spring 則是通過 IOC 容器來創建對象,也就是說我們將創建對象的控制權交給了 IOC 容器。IOC 讓程序員不再關注怎么去創建對象,而是關注與對象創建之后的操作,把對象的創建、初始化、銷毀等工作交給spring容器來做。
- IOC很好的體現了面向對象設計法則之一—— 好萊塢法則:“別找我們,我們找你”;即由IoC容器幫對象找相應的依賴對象並注入,而不是由對象主動去找。
IOC的優點是什么?
IOC 或 依賴注入把應用的代碼量降到最低。它使應用容易測試,單元測試不再需要單例和JNDI查找機制。最小的代價和最小的侵入性使松散耦合得以實現。IOC容器支持加載服務時的餓漢式初始化和懶加載。
什么是Spring的依賴注入?有哪些方法進行依賴注入
- 依賴注入,是IOC的一個方面,是個通常的概念,它有多種解釋。這概念是說你不用創建對象,而只需要描述它如何被創建。你不在代碼里直接組裝你的組件和服務,但是要在配置文件里描述哪些組件需要哪些服務,之后一個容器(IOC容器)負責把他們組裝起來。
- 依賴注入是在編譯階段尚未知所需的功能是來自哪個的類的情況下,將其他對象所依賴的功能對象實例化的模式。
- 構造器依賴注入:構造器依賴注入通過容器觸發一個類的構造器來實現的,該類有一系列參數,每個參數代表一個對其他類的依賴。
- Setter 方 法 注 入 :Setter 方 法 注 入 是 容 器 通 過 調 用 無 參構 造 器 或 無 參 static 工 廠 方 法 實 例 化 bean 之 后 , 調 用該 bean 的 setter 方 法 , 即 實 現 了 基 於 setter 的 依 賴 注入 。
IOC和工廠模式的區別
工廠模式如果增加了新的類需要從新編譯工廠類。SpringIoc通過反射機制,不需要從新編譯代碼,因為它的對象都是動態生成的。
哪種依賴注入方式你建議使用,構造器注入,還是 Setter方法注入,甚至是接口注入?
你兩種依賴方式都可以使用,構造器注入和Setter方法注入。最好的解決方案是用構造器參數實現強制依賴,setter方法實現可選依賴。
控制反轉如何實現:
我們每次使用spring框架都要配置xml文件,這個xml配置了bean的id和class。
spring中默認的bean為單實例模式,通過bean的class引用反射機制可以創建這個實例。
因此,spring框架通過反射替我們創建好了實例並且替我們維護他們。
A需要引用B類,spring框架就會通過xml把B實例的引用傳給了A的成員變量。
什么是Spring beans?
Spring beans 是那些形成Spring應用的主干的java對象。它們被Spring IOC容器初始化,裝配,和管理。這些beans通過容器中配置的元數據創建。比如,以XML文件中
Spring 框架定義的beans都是單件beans。在bean tag中有個屬性”singleton”,如果它被賦為TRUE,bean 就是單件,否則就是一個 prototype bean。默認是TRUE,所以所有在Spring框架中的beans 缺省都是單件
一個 Spring Bean 定義 包含什么?
一個Spring Bean 的定義包含容器必知的所有配置元數據,包括如何創建一個bean,它的生命周期詳情及它的依賴。
解釋Spring支持的幾種bean的作用域。
singleton:
Spring IoC容器中只會存在一個共享的Bean實例,無論有多少個Bean引用它,始終指向同一對象。Singleton作用域是Spring中的缺省作用域。
prototype:
每次通過Spring容器獲取prototype定義的bean時,容器都將創建一個新的Bean實例,每個Bean實例都有自己的屬性和狀態,而singleton全局只有一個對象。
request:
在一次Http請求中,容器會返回該Bean的同一實例。而對不同的Http請求則會產生新的Bean,而且該bean僅在當前Http Request內有效。
session:
在一次Http Session中,容器會返回該Bean的同一實例。而對不同的Session請求則會創建新的實例,該bean實例僅在當前Session內有效。
global Session:
在一個全局的Http Session中,容器會返回該Bean的同一個實例,僅在使用portlet context時有效。
解釋Spring框架中bean的生命周期。
- 實例化一個Bean,也就是我們通常說的new。
- 按照Spring上下文對實例化的Bean進行配置,也就是IOC注入。
- 如果這個Bean實現了BeanNameAware接口,會調用它實現的setBeanName(String beanId)方法,此處傳遞的是Spring配置文件中Bean的ID。
- 如果這個Bean實現了BeanFactoryAware接口,會調用它實現的setBeanFactory(),傳遞的是Spring工廠本身(可以用這個方法獲取到其他Bean)。
- 如果這個Bean實現了ApplicationContextAware接口,會調用setApplicationContext(ApplicationContext)方法,傳入Spring上下文。
- 如果這個Bean關聯了BeanPostProcessor接口,將會調用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor經常被用作是Bean內容的更改,並且由於這個是在Bean初始化結束時調用After方法,也可用於內存或緩存技術。
- 如果這個Bean在Spring配置文件中配置了init-method屬性會自動調用其配置的初始化方法。
- 如果這個Bean關聯了BeanPostProcessor接口,將會調用postAfterInitialization(Object obj, String s)方法。
- 當Bean不再需要時,會經過清理階段,如果Bean實現了DisposableBean接口,會調用其實現的destroy方法。
- 最后,如果這個Bean的Spring配置中配置了destroy-method屬性,會自動調用其配置的銷毀方法。
對Spring中依賴注入兩種方式的認識
兩種注入方式為:構造方法注入和設值注入
- 設值注入與傳統的JavaBean的寫法更相似,程序員更容易理解、接受,通過setter方式設定依賴關系顯得更加直觀、明顯;
- 對於復雜的依賴關系,如果采用構造注入,會導致構造器過於臃腫,難以閱讀。Spring在創建Bean實例時,需要同時實例化其依賴的全部實例,因而會產生浪費。而使用設置注入,則避免這下問題;
- 在某些屬性可選的情況下,多參數的構造器更加笨拙,官方更鼓勵使用設值注入。
- 構造注入可以在構造器中決定依賴關系的注入順序,優先依賴的優先注入。
- 對於依賴關系無須變化的Bean,構造注入更有用處,因為沒有setter方法,所有的依賴關系全部在構造器內設定,因此,不用擔心后續代碼對依賴關系的破壞。
- 構造注入使依賴關系只能在構造器中設定,則只有組件的創建者才能改變組件的依賴關系。對組件的調用者而言,組件內部的依賴關系完全透明,更符合高內聚的原則。
- 設值注入不會重寫構造方法的值。如果我們對同一個變量同時使用了構造方法注入又使用了設置方法注入的話,那么構造方法將不能覆蓋由設值方法注入的值。
- 建議采用以設值注入為主,構造注入為輔的注入策略。對於依賴關系無須變化的注入,盡量采用構造注入;而其他的依賴關系的注入,則考慮采用set注入。
在 Spring中如何注入一個java集合?
Spring提供以下幾種集合的配置元素:
類型用於注入一列值,允許有相同的值。
Spring框架中的單例bean是線程安全的嗎?
Spring框架不對單例的bean做任何多線程的處理。單例的bean的並發問題和線程安全是開發人員的責任。
而實際上,大多數spring bean沒有可變狀態(例如服務和DAO的類),這樣的話本身是線程安全的。但如果您的bean有可變狀態(例如視圖模型對象),這就需要你來確保線程安全。
這個問題最簡單和明顯的解決方案是改變bean Scope,可變的bean從“單例”到“原型”。
什么是Spring的內部bean?
當一個bean僅被用作另一個bean的屬性時,它能被聲明為一個內部bean。
為了定義inner bean,在Spring 的 基於XML 的 配置元數據中,可以在
解釋不同方式的自動裝配 。
有五種自動裝配的方式,用來指導Spring容器用自動裝配方式進行依賴注入。
no:默認的方式是不進行自動裝配,通過顯式設置ref 屬性來進行裝配。
byName:通過參數名 自動裝配,Spring容器在配置文件中發現bean的autowire屬性被設置成byname,之后容器試圖匹配、裝配和該bean的屬性具有相同名字的bean。
byType::通過參數類型自動裝配,Spring容器在配置文件中發現bean的autowire屬性被設置成byType,之后容器試圖匹配、裝配和該bean的屬性具有相同類型的bean。如果有多個bean符合條件,則拋出錯誤。
constructor:這個方式類似於byType, 但是要提供給構造器參數,如果沒有確定的帶參數的構造器參數類型,將會拋出異常。
autodetect:首先嘗試使用constructor來自動裝配,如果無法工作,則使用byType方式。
自動裝配的局限性是:
- 重寫: 你仍需用
和 配置來定義依賴,意味着總要重寫自動裝配。 - 基本數據類型: 你不能自動裝配簡單的屬性,如基本數據類型,String字符串和類。
- 模糊特性: 自動裝配不如顯式裝配精確,如果有可能,建議使用顯式裝配。
什么是AOP?
- 在運行時,動態地將代碼切入到類的指定方法、指定位置上的編程思想就是面向切面的編程,也就是AOP。
- AOP是Spring提供的關鍵特性之一。AOP即面向切面編程,是OOP編程的有效補充。
- 使用AOP技術,可以將一些系統性相關的編程工作,獨立提取出來,獨立實現,然后通過切面切入進系統。
- 從而避免了在業務邏輯的代碼中混入很多的系統相關的邏輯——比如權限管理,事物管理,日志記錄等等。
- 這些系統性的編程工作都可以獨立編碼實現,然后通過AOP技術切入進系統即可。從而達到了 將不同的關注點分離出來的效果。
AOP的重要概念有哪些?
- Aspect :切面,切入系統的一個切面。比如事務管理是一個切面,權限管理也是一個切面;
- Join point :連接點,也就是可以進行橫向切入的位置;
- Advice :通知,切面在某個連接點執行的操作
- Pointcut :切點,符合切點表達式的連接點,也就是真正被切入的地方;
簡單介紹一下AOP 的實現原理
AOP分為靜態AOP和動態AOP。
- 靜態AOP:靜態AOP是指AspectJ實現的AOP,他是將切面代碼直接編譯到Java類文件中。
- 動態AOP:動態AOP是指將切面代碼進行動態織入實現的AOP。
Spring的AOP為動態AOP,實現的技術原理是JDK提供的動態代理技術 和 CGLIB(動態字節碼增強技術) 。盡管實現技術不一樣,但 都是基於代理模式 , 都是生成一個代理對象 。
在Spring AOP中關注點和橫切關注點有什么不同?
關注點是我們想在應用的模塊中實現的行為。關注點可以被定義為:我們想實現以解決特定業務問題的方法。比如,在所有電子商務應用中,不同的關注點(或者模塊)可能是庫存管理、航運管理、用戶管理等。
橫切關注點是貫穿整個應用程序的關注點。像日志、安全和數據轉換,它們在應用的每一個模塊都是必須的,所以他們是一種橫切關注點。
Spring中有哪些不同的通知類型?
通知(advice)是你在你的程序中想要應用在其他模塊中的橫切關注點的實現。Advice主要有以下5種類型:
- 前置通知(Before Advice):在連接點之前執行的Advice,不過除非它拋出異常,否則沒有能力中斷執行流。使用
@Before
注解使用這個Advice。 - 返回之后通知(After Retuning Advice): 在連接點正常結束之后執行的Advice。例如,如果一個方法沒有拋出異常正常返回。通過
@AfterReturning
關注使用它。 - 拋出(異常)后執行通知(After Throwing Advice): 如果一個方法通過拋出異常來退出的話,這個Advice就會被執行。通用
@AfterThrowing
注解來使用。 - 后置通知(After Advice):無論連接點是通過什么方式退出的(正常返回或者拋出異常)都會執行在結束后執行這些Advice。通過
@After
注解使用。 - 圍繞通知(Around Advice): 圍繞連接點執行的Advice,就你一個方法調用。這是最強大的Advice。通過
@Around
注解使用。
Spring AOP 代理是什么?主要的兩種方式
- 代理是使用非常廣泛的設計模式。簡單來說,代理是一個看其他像另一個對象的對象,但它添加了一些特殊的功能。
- Spring AOP是基於代理實現的。AOP 代理是一個由 AOP 框架創建的用於在運行時實現切面協議的對象。
- Spring AOP默認為 AOP 代理使用標准的 JDK 動態代理。這使得任何接口(或者接口的集合)可以被代理。Spring AOP 也可以使用 CGLIB 代理。這對代理類而不是接口是必須的。
- 如果業務對象沒有實現任何接口那么默認使用CGLIB。
- JDK動態代理:JDK動態代理通過反射來接收被代理的類,並且要求被代理的類必須實現一個接口,JDK動態代理的核心是InvocationHandler接口和Proxy類
- CGLIB動態代理:如果目標沒有實現接口,那么SpringAOP會選擇使用CGLIB來動態代理目標類,當然Spring也支持配置強制使用CGLIB動態來歷。
- CGLIB是一個代碼生成的類庫,可以在運行時動態的生成某個類的子類。
- 注意:CGLIB是通過集成的方式做的動態代理,因此如果某個類被標記為final,那么它無法使用CGLIB做動態代理
解釋一下Spring AOP里面的幾個名詞:
- 切面(Aspect):被抽取的公共模塊,可能會橫切多個對象。 在Spring AOP中,切面可以使用通用類(基於模式的風格) 或者在普通類中以 @AspectJ 注解來實現。
- 連接點(Join point):指方法,在Spring AOP中,一個連接點 總是 代表一個方法的執行。
- 通知(Advice):在切面的某個特定的連接點(Join point)上執行的動作。通知有各種類型,其中包括“around”、“before”和“after”等通知。許多AOP框架,包括Spring,都是以攔截器做通知模型, 並維護一個以連接點為中心的攔截器鏈。
- 切入點(Pointcut):切入點是指 我們要對哪些Join point進行攔截的定義。通過切入點表達式,指定攔截的方法,比如指定攔截add、search。
- 引入(Introduction):(也被稱為內部類型聲明(inter-type declaration))。聲明額外的方法或者某個類型的字段。Spring允許引入新的接口(以及一個對應的實現)到任何被代理的對象。例如,你可以使用一個引入來使bean實現 IsModified 接口,以便簡化緩存機制。
- 目標對象(Target Object): 被一個或者多個切面(aspect)所通知(advise)的對象。也有人把它叫做 被通知(adviced) 對象。 既然Spring AOP是通過運行時代理實現的,這個對象永遠是一個 被代理(proxied) 對象。
- 織入(Weaving):指把增強應用到目標對象來創建新的代理對象的過程。Spring是在運行時完成織入。
- 切入點(pointcut)和連接點(join point)匹配的概念是AOP的關鍵,這使得AOP不同於其它僅僅提供攔截功能的舊技術。 切入點使得定位通知(advice)可獨立於OO層次。 例如,一個提供聲明式事務管理的around通知可以被應用到一組橫跨多個對象中的方法上(例如服務層的所有業務操作)。
引介(Introduction)是什么?
引介讓一個切面可以聲明被通知的對象實現了任何他們沒有真正實現的額外接口,而且為這些對象提供接口的實現。
可以使用 @DeclareParaents
注解來生成一個引介。
連接點(Joint Point)和切入點(Point cut)是什么?
- 連接點是程序執行的一個點。例如,一個方法的執行或者一個異常的處理。在 Spring AOP 中,一個連接點總是代表一個方法執行。舉例來說,所有定義在你的
EmpoyeeManager
接口中的方法都可以被認為是一個連接點,如果你在這些方法上使用橫切關注點的話。 - 切入點(切入點)是一個匹配連接點的斷言或者表達式。Advice 與切入點表達式相關聯,並在切入點匹配的任何連接點處運行(比如,表達式
execution(* EmployeeManager.getEmployeeById(...))
可以匹配EmployeeManager
接口的getEmployeeById()
)。由切入點表達式匹配的連接點的概念是 AOP 的核心。Spring 默認使用 AspectJ 切入點表達式語言。
什么是織入(weaving)?
- 織入是將切面與外部的應用類型或者類連接起來以創建通知對象(adviced object)的過程。這可以在編譯時(比如使用 AspectJ 編譯器)、加載時或者運行時完成。
- Spring AOP 跟其他純 Java AOP 框架一樣,只在運行時執行織入。在協議上,AspectJ 框架支持編譯時和加載時織入。
- AspectJ 編譯時織入是通過一個叫做 ajc 特殊的 AspectJ 編譯器完成的。它可以將切面織入到你的 Java 源碼文件中,然后輸出織入后的二進制 class 文件。它也可以將切面織入你的編譯后的 class 文件或者 Jar 文件。這個過程叫做后編譯時織入(post-compile-time weaving)。
- 在 Spring IoC 容器中聲明你的類之前,你可以為它們運行編譯時和后編譯時織入。Spring 完全沒有被包含到織入的過程中。
- AspectJ 加載時織入(load-time weaving, LTW)在目標類被類加載器加載到JVM時觸發。對於一個被織入的對象,需要一個特殊的類加載器來增強目標類的字節碼。AspectJ 和 Spring 都提供了加載時織入器以為類加載添加加載時織入的能力。你只需要簡單的配置就可以打開這個加載時織入器。
Spring通知有哪些類型?
- 前置通知(Before advice):在某連接點(join point)之前執行的通知,但這個通知不能阻止連接點前的執行(除非它拋出一個異常)。
- 返回后通知(After returning advice):在某連接點(join point)正常完成后執行的通知:例如,一個方法沒有拋出任何異常,正常返回。
- 拋出異常后通知(After throwing advice):在方法拋出異常退出時執行的通知。
- 后通知(After (finally) advice):當某連接點退出的時候執行的通知(不論是正常返回還是異常退出)。
- 環繞通知(Around Advice):包圍一個連接點(join point)的通知,如方法調用。這是最強大的一種通知類型。 環繞通知可以在方法調用前后完成自定義的行為。它也會選擇是否繼續執行連接點或直接返回它們自己的返回值或拋出異常來結束執行。 環繞通知是最常用的一種通知類型。大部分基於攔截的AOP框架,例如Nanning和JBoss4,都只提供環繞通知。
@Autowired 與@Resource的區別
- @Autowired與@Resource都可以用來裝配bean. 都可以寫在字段上,或寫在setter方法上。
- @Autowired默認按類型裝配(這個注解是屬於spring的),默認情況下必須要求依賴對象必須存在,如果要允許null值,可以設置它的required屬性為false,如:@Autowired(required=false) ,如果我們想使用名稱裝配可以結合@Qualifier注解進行
- @Resource(這個注解屬於J2EE的),默認安裝名稱進行裝配,名稱可以通過name屬性進行指定,如果沒有指定name屬性,當注解寫在字段上時,默認取字段名進行安裝名稱查找,如果注解寫在setter方法上默認取屬性名進行裝配。當找不到與名稱匹配的bean時才按照類型進行裝配。但是需要注意的是,如果name屬性一旦指定,就只會按照名稱進行裝配。
Spring框架中都用到了哪些設計模式?
- 代理模式:在AOP和remoting中被用的比較多。
- 單例模式:在spring配置文件中定義的bean默認為單例模式。
- 模板方法模式:用來解決代碼重復的問題。
- 前端控制器模式:Spring提供了DispatcherServlet來對請求進行分發。
- 依賴注入模式:貫穿於BeanFactory / ApplicationContext接口的核心理念。
- 工廠模式:BeanFactory用來創建對象的實例。
Spring如何處理線程並發問題?
在一般情況下,只有無狀態的Bean才可以在多線程環境下共享,在Spring中,絕大部分Bean都可以聲明為singleton作用域,因為Spring對一些Bean中非線程安全狀態采用ThreadLocal進行處理,解決線程安全問題。
ThreadLocal和線程同步機制都是為了解決多線程中相同變量的訪問沖突問題。同步機制采用了“時間換空間”的方式,僅提供一份變量,不同的線程在訪問前需要獲取鎖,沒獲得鎖的線程則需要排隊。而ThreadLocal采用了“空間換時間”的方式。
ThreadLocal會為每一個線程提供一個獨立的變量副本,從而隔離了多個線程對數據的訪問沖突。因為每一個線程都擁有自己的變量副本,從而也就沒有必要對該變量進行同步了。ThreadLocal提供了線程安全的共享對象,在編寫多線程代碼時,可以把不安全的變量封裝進ThreadLocal。
在Spring框架中如何更有效地使用JDBC?
使用SpringJDBC 框架,資源管理和錯誤處理的代價都會被減輕。所以開發者只需寫statements 和 queries從數據存取數據,JDBC也可以在Spring框架提供的模板類的幫助下更有效地被使用,這個模板叫JdbcTemplate
Spring支持的事務管理類型?
- 編程式事務管理: 這意味你通過編程的方式管理事務,給你帶來極大的靈活性,但是難維護。
- 聲明式事務管理: 這意味着你可以將業務代碼和事務管理分離,你只需用注解和XML配置來管理事務。
你更傾向用那種事務管理類型?
大多數Spring框架的用戶選擇聲明式事務管理,因為它對應用代碼的影響最小,因此更符合一個無侵入的輕量級容器的思想。聲明式事務管理要優於編程式事務管理,雖然比編程式事務管理(這種方式允許你通過代碼控制事務)少了一點靈活性。
spring事務的隔離級別和傳播行為
隔離級別:
- DEFAULT使用數據庫默認的隔離級別
- READ_UNCOMMITTED會出現臟讀,不可重復讀和幻影讀問題
- READ_COMMITTED會出現重復讀和幻影讀
- REPEATABLE_READ會出現幻影讀
- SERIALIZABLE最安全,但是代價最大,性能影響極其嚴重
和傳播行:
- REQUIRED存在事務就融入該事務,不存在就創建事務
- SUPPORTS存在事務就融入事務,不存在則不創建事務
- MANDATORY存在事務則融入該事務,不存在,拋異常
- REQUIRES_NEW總是創建新事務
- NOT_SUPPORTED存在事務則掛起,一直執行非事務操作
- NEVER總是執行非事務,如果當前存在事務則拋異常
- NESTED嵌入式事務