Spring常見問題總結(jié)

1. 什么是 Spring 框架?

Spring 是一種輕量級(jí)開發(fā)框架雄右,旨在提高開發(fā)人員的開發(fā)效率以及系統(tǒng)的可維護(hù)性慷彤。Spring 官網(wǎng):https://spring.io/估蹄。

我們一般說 Spring 框架指的都是 Spring Framework脸爱,它是很多模塊的集合狞玛,使用這些模塊可以很方便地協(xié)助我們進(jìn)行開發(fā)剖笙。這些模塊是:核心容器卵洗、數(shù)據(jù)訪問/集成,、Web弥咪、AOP(面向切面編程)过蹂、工具、消息和測(cè)試模塊聚至。比如:Core Container 中的 Core 組件是Spring 所有組件的核心酷勺,Beans 組件和 Context 組件是實(shí)現(xiàn)IOC和依賴注入的基礎(chǔ),AOP組件用來實(shí)現(xiàn)面向切面編程扳躬。

Spring 官網(wǎng)列出的 Spring 的 6 個(gè)特征:

  • 核心技術(shù) :依賴注入(DI)脆诉,AOP,事件(events)贷币,資源击胜,i18n,驗(yàn)證役纹,數(shù)據(jù)綁定潜的,類型轉(zhuǎn)換,SpEL字管。
  • 測(cè)試 :模擬對(duì)象啰挪,TestContext框架信不,Spring MVC 測(cè)試,WebTestClient亡呵。
  • 數(shù)據(jù)訪問 :事務(wù)抽活,DAO支持,JDBC锰什,ORM下硕,編組XML。
  • Web支持 : Spring MVC和Spring WebFlux Web框架汁胆。
  • 集成 :遠(yuǎn)程處理梭姓,JMS,JCA嫩码,JMX誉尖,電子郵件,任務(wù)铸题,調(diào)度铡恕,緩存。
  • 語(yǔ)言 :Kotlin丢间,Groovy探熔,動(dòng)態(tài)語(yǔ)言。

2. 列舉一些重要的Spring模塊烘挫?

下圖對(duì)應(yīng)的是 Spring4.x 版本诀艰。目前最新的5.x版本中 Web 模塊的 Portlet 組件已經(jīng)被廢棄掉,同時(shí)增加了用于異步響應(yīng)式處理的 WebFlux 組件饮六。


  • Spring Core: 基礎(chǔ),可以說 Spring 其他所有的功能都需要依賴于該類庫(kù)涡驮。主要提供 IoC 依賴注入功能。
  • Spring Aspects : 該模塊為與AspectJ的集成提供支持喜滨。
  • Spring AOP :提供了面向切面的編程實(shí)現(xiàn)捉捅。
  • Spring JDBC : Java數(shù)據(jù)庫(kù)連接。
  • Spring JMS :Java消息服務(wù)虽风。
  • Spring ORM : 用于支持Hibernate等ORM工具棒口。
  • Spring Web : 為創(chuàng)建Web應(yīng)用程序提供支持。
  • Spring Test : 提供了對(duì) JUnit 和 TestNG 測(cè)試的支持辜膝。

3. @RestController vs @Controller

Controller 返回一個(gè)頁(yè)面

單獨(dú)使用 @Controller 不加 @ResponseBody的話一般使用在要返回一個(gè)視圖的情況无牵,這種情況屬于比較傳統(tǒng)的Spring MVC 的應(yīng)用,對(duì)應(yīng)于前后端不分離的情況厂抖。

@RestController 返回JSON 或 XML 形式數(shù)據(jù)

@RestController只返回對(duì)象茎毁,對(duì)象數(shù)據(jù)直接以 JSON 或 XML 形式寫入 HTTP 響應(yīng)(Response)中,這種情況屬于 RESTful Web服務(wù),這也是目前日常開發(fā)所接觸的最常用的情況(前后端分離)七蜘。

SpringMVC+RestController

@Controller +@ResponseBody 返回JSON 或 XML 形式數(shù)據(jù)

如果你需要在Spring4之前開發(fā) RESTful Web服務(wù)的話谭溉,你需要使用@Controller 并結(jié)合@ResponseBody注解,也就是說@Controller +@ResponseBody= @RestController(Spring 4 之后新加的注解)橡卤。

@ResponseBody 注解的作用是將 Controller 的方法返回的對(duì)象通過適當(dāng)?shù)霓D(zhuǎn)換器轉(zhuǎn)換為指定的格式之后扮念,寫入到HTTP 響應(yīng)(Response)對(duì)象的 body 中,通常用來返回 JSON 或者 XML 數(shù)據(jù)碧库,返回 JSON 數(shù)據(jù)的情況比較多柜与。

Reference:

4. Spring IOC & AOP

4.1 談?wù)勛约簩?duì)于 Spring IoC 和 AOP 的理解

IoC

IoC(Inverse of Control:控制反轉(zhuǎn))是一種設(shè)計(jì)思想,就是 將原本在程序中手動(dòng)創(chuàng)建對(duì)象的控制權(quán)嵌灰,交由Spring框架來管理弄匕。 IoC 在其他語(yǔ)言中也有應(yīng)用,并非 Spring 特有沽瞭。 IoC 容器是 Spring 用來實(shí)現(xiàn) IoC 的載體迁匠, IoC 容器實(shí)際上就是個(gè)Map(key,value),Map 中存放的是各種對(duì)象秕脓。

將對(duì)象之間的相互依賴關(guān)系交給 IoC 容器來管理,并由 IoC 容器完成對(duì)象的注入儒搭。這樣可以很大程度上簡(jiǎn)化應(yīng)用的開發(fā)吠架,把應(yīng)用從復(fù)雜的依賴關(guān)系中解放出來。 IoC 容器就像是一個(gè)工廠一樣搂鲫,當(dāng)我們需要?jiǎng)?chuàng)建一個(gè)對(duì)象的時(shí)候傍药,只需要配置好配置文件/注解即可,完全不用考慮對(duì)象是如何被創(chuàng)建出來的魂仍。 在實(shí)際項(xiàng)目中一個(gè) Service 類可能有幾百甚至上千個(gè)類作為它的底層拐辽,假如我們需要實(shí)例化這個(gè) Service,你可能要每次都要搞清這個(gè) Service 所有底層類的構(gòu)造函數(shù)擦酌,這可能會(huì)把人逼瘋俱诸。如果利用 IoC 的話,你只需要配置好赊舶,然后在需要的地方引用就行了睁搭,這大大增加了項(xiàng)目的可維護(hù)性且降低了開發(fā)難度。

Spring 時(shí)代我們一般通過 XML 文件來配置 Bean笼平,后來開發(fā)人員覺得 XML 文件來配置不太好园骆,于是 SpringBoot 注解配置就慢慢開始流行起來。

推薦閱讀:https://www.zhihu.com/question/23277575/answer/169698662

Spring IoC的初始化過程:

IoC源碼閱讀

AOP

AOP(Aspect-Oriented Programming:面向切面編程)能夠?qū)⒛切┡c業(yè)務(wù)無關(guān)寓调,卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯或責(zé)任(例如事務(wù)處理锌唾、日志管理、權(quán)限控制等)封裝起來夺英,便于減少系統(tǒng)的重復(fù)代碼晌涕,降低模塊間的耦合度滋捶,并有利于未來的可拓展性和可維護(hù)性

Spring AOP就是基于動(dòng)態(tài)代理的渐排,如果要代理的對(duì)象炬太,實(shí)現(xiàn)了某個(gè)接口,那么Spring AOP會(huì)使用JDK Proxy驯耻,去創(chuàng)建代理對(duì)象亲族,而對(duì)于沒有實(shí)現(xiàn)接口的對(duì)象,就無法使用 JDK Proxy 去進(jìn)行代理了可缚,這時(shí)候Spring AOP會(huì)使用Cglib 霎迫,這時(shí)候Spring AOP會(huì)使用 Cglib 生成一個(gè)被代理對(duì)象的子類來作為代理,如下圖所示:

當(dāng)然你也可以使用 AspectJ ,Spring AOP 已經(jīng)集成了AspectJ 帘靡,AspectJ 應(yīng)該算的上是 Java 生態(tài)系統(tǒng)中最完整的 AOP 框架了知给。

使用 AOP 之后我們可以把一些通用功能抽象出來,在需要用到的地方直接使用即可描姚,這樣大大簡(jiǎn)化了代碼量涩赢。我們需要增加新功能時(shí)也方便,這樣也提高了系統(tǒng)擴(kuò)展性轩勘。日志功能筒扒、事務(wù)管理等等場(chǎng)景都用到了 AOP 。

4.2 Spring AOP 和 AspectJ AOP 有什么區(qū)別绊寻?

Spring AOP 屬于運(yùn)行時(shí)增強(qiáng)花墩,而 AspectJ 是編譯時(shí)增強(qiáng)。 Spring AOP 基于代理(Proxying)澄步,而 AspectJ 基于字節(jié)碼操作(Bytecode Manipulation)冰蘑。

Spring AOP 已經(jīng)集成了 AspectJ ,AspectJ 應(yīng)該算的上是 Java 生態(tài)系統(tǒng)中最完整的 AOP 框架了村缸。AspectJ 相比于 Spring AOP 功能更加強(qiáng)大祠肥,但是 Spring AOP 相對(duì)來說更簡(jiǎn)單,

如果我們的切面比較少梯皿,那么兩者性能差異不大搪柑。但是,當(dāng)切面太多的話索烹,最好選擇 AspectJ 工碾,它比Spring AOP 快很多。

5. Spring bean

5.1 Spring 中的 bean 的作用域有哪些?

  • singleton : 唯一 bean 實(shí)例百姓,Spring 中的 bean 默認(rèn)都是單例的渊额。
  • prototype : 每次請(qǐng)求都會(huì)創(chuàng)建一個(gè)新的 bean 實(shí)例。
  • request : 每一次HTTP請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的bean,該bean僅在當(dāng)前HTTP request內(nèi)有效旬迹。
  • session : 每一次HTTP請(qǐng)求都會(huì)產(chǎn)生一個(gè)新的 bean火惊,該bean僅在當(dāng)前 HTTP session 內(nèi)有效。
  • global-session: 全局session作用域奔垦,僅僅在基于portlet的web應(yīng)用中才有意義屹耐,Spring5已經(jīng)沒有了。Portlet是能夠生成語(yǔ)義代碼(例如:HTML)片段的小型Java Web插件椿猎。它們基于portlet容器惶岭,可以像servlet一樣處理HTTP請(qǐng)求。但是犯眠,與 servlet 不同按灶,每個(gè) portlet 都有不同的會(huì)話

5.2 Spring 中的單例 bean 的線程安全問題了解嗎?

大部分時(shí)候我們并沒有在系統(tǒng)中使用多線程筐咧,所以很少有人會(huì)關(guān)注這個(gè)問題鸯旁。單例 bean 存在線程問題,主要是因?yàn)楫?dāng)多個(gè)線程操作同一個(gè)對(duì)象的時(shí)候量蕊,對(duì)這個(gè)對(duì)象的非靜態(tài)成員變量的寫操作會(huì)存在線程安全問題铺罢。

常見的有兩種解決辦法:

  1. 在Bean對(duì)象中盡量避免定義可變的成員變量(不太現(xiàn)實(shí))。

  2. 在類中定義一個(gè)ThreadLocal成員變量残炮,將需要的可變成員變量保存在 ThreadLocal 中(推薦的一種方式)韭赘。

5.3 @Component 和 @Bean 的區(qū)別是什么?

  1. 作用對(duì)象不同: @Component 注解作用于類吉殃,而@Bean注解作用于方法辞居。
  2. @Component通常是通過類路徑掃描來自動(dòng)偵測(cè)以及自動(dòng)裝配到Spring容器中(我們可以使用 @ComponentScan 注解定義要掃描的路徑從中找出標(biāo)識(shí)了需要裝配的類自動(dòng)裝配到 Spring 的 bean 容器中)楷怒。@Bean 注解通常是我們?cè)跇?biāo)有該注解的方法中定義產(chǎn)生這個(gè) bean,@Bean告訴了Spring這是某個(gè)類的示例蛋勺,當(dāng)我需要用它的時(shí)候還給我。
  3. @Bean 注解比 Component 注解的自定義性更強(qiáng)鸠删,而且很多地方我們只能通過 @Bean 注解來注冊(cè)bean抱完。比如當(dāng)我們引用第三方庫(kù)中的類需要裝配到 Spring容器時(shí),則只能通過 @Bean來實(shí)現(xiàn)刃泡。

@Bean注解使用示例:

@Configuration
public class AppConfig {
    @Bean
    public TransferService transferService() {
        return new TransferServiceImpl();
    }

}

上面的代碼相當(dāng)于下面的 xml 配置

<beans>
    <bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>

下面這個(gè)例子是通過 @Component 無法實(shí)現(xiàn)的巧娱。

@Bean
public OneService getService(status) {
    case (status)  {
        when 1:
                return new serviceImpl1();
        when 2:
                return new serviceImpl2();
        when 3:
                return new serviceImpl3();
    }
}

5.4 將一個(gè)類聲明為Spring的 bean 的注解有哪些?

我們一般使用 @Autowired 注解自動(dòng)裝配 bean,要想把類標(biāo)識(shí)成可用于 @Autowired 注解自動(dòng)裝配的 bean 的類,采用以下注解可實(shí)現(xiàn):

  • @Component :通用的注解烘贴,可標(biāo)注任意類為 Spring 組件禁添。如果一個(gè)Bean不知道屬于哪個(gè)層,可以使用@Component 注解標(biāo)注桨踪。
  • @Repository : 對(duì)應(yīng)持久層即 Dao 層老翘,主要用于數(shù)據(jù)庫(kù)相關(guān)操作。
  • @Service : 對(duì)應(yīng)服務(wù)層,主要涉及一些復(fù)雜的邏輯铺峭,需要用到 Dao層墓怀。
  • @Controller : 對(duì)應(yīng) Spring MVC 控制層,主要用于接受用戶請(qǐng)求并調(diào)用 Service 層返回?cái)?shù)據(jù)給前端頁(yè)面卫键。

5.5 Spring 中的 bean 生命周期?

這部分網(wǎng)上有很多文章都講到了傀履,下面的內(nèi)容整理自:https://yemengying.com/2016/07/14/spring-bean-life-cycle/ ,除了這篇文章莉炉,再推薦一篇很不錯(cuò)的文章 :https://www.cnblogs.com/zrtqsk/p/3735273.html 钓账。

  • Bean 容器找到配置文件中 Spring Bean 的定義灶壶。
  • Bean 容器利用 Java Reflection API 創(chuàng)建一個(gè)Bean的實(shí)例优炬。
  • 如果涉及到一些屬性值 利用 set()方法設(shè)置一些屬性值。
  • 如果 Bean 實(shí)現(xiàn)了 BeanNameAware 接口芙委,調(diào)用 setBeanName()方法羞福,傳入Bean的名字惕蹄。
  • 如果 Bean 實(shí)現(xiàn)了 BeanClassLoaderAware 接口,調(diào)用 setBeanClassLoader()方法治专,傳入 ClassLoader對(duì)象的實(shí)例卖陵。
  • 與上面的類似,如果實(shí)現(xiàn)了其他 *.Aware接口张峰,就調(diào)用相應(yīng)的方法泪蔫。
  • 如果有和加載這個(gè) Bean 的 Spring 容器相關(guān)的 BeanPostProcessor 對(duì)象,執(zhí)行postProcessBeforeInitialization() 方法
  • 如果Bean實(shí)現(xiàn)了InitializingBean接口喘批,執(zhí)行afterPropertiesSet()方法撩荣。
  • 如果 Bean 在配置文件中的定義包含 init-method 屬性,執(zhí)行指定的方法饶深。
  • 如果有和加載這個(gè) Bean的 Spring 容器相關(guān)的 BeanPostProcessor 對(duì)象餐曹,執(zhí)行postProcessAfterInitialization() 方法
  • 當(dāng)要銷毀 Bean 的時(shí)候,如果 Bean 實(shí)現(xiàn)了 DisposableBean 接口敌厘,執(zhí)行 destroy() 方法台猴。
  • 當(dāng)要銷毀 Bean 的時(shí)候,如果 Bean 在配置文件中的定義包含 destroy-method 屬性俱两,執(zhí)行指定的方法饱狂。

圖示:


與之比較類似的中文版本:


6. Spring MVC

6.1 說說自己對(duì)于 Spring MVC 了解?

談到這個(gè)問題,我們不得不提提之前 Model1 和 Model2 這兩個(gè)沒有 Spring MVC 的時(shí)代宪彩。

  • Model1 時(shí)代 : 很多學(xué) Java 后端比較晚的朋友可能并沒有接觸過 Model1 模式下的 JavaWeb 應(yīng)用開發(fā)休讳。在 Model1 模式下,整個(gè) Web 應(yīng)用幾乎全部用 JSP 頁(yè)面組成尿孔,只用少量的 JavaBean 來處理數(shù)據(jù)庫(kù)連接俊柔、訪問等操作磺樱。這個(gè)模式下 JSP 既是控制層又是表現(xiàn)層。顯而易見婆咸,這種模式存在很多問題竹捉。比如①將控制邏輯和表現(xiàn)邏輯混雜在一起,導(dǎo)致代碼重用率極低尚骄;②前端和后端相互依賴块差,難以進(jìn)行測(cè)試并且開發(fā)效率極低;
  • Model2 時(shí)代 :學(xué)過 Servlet 并做過相關(guān) Demo 的朋友應(yīng)該了解“Java Bean(Model)+ JSP(View,)+Servlet(Controller) ”這種開發(fā)模式,這就是早期的 JavaWeb MVC 開發(fā)模式倔丈。Model:系統(tǒng)涉及的數(shù)據(jù)憨闰,也就是 dao 和 bean。View:展示模型中的數(shù)據(jù)需五,只是用來展示鹉动。Controller:處理用戶請(qǐng)求都發(fā)送給 ,返回?cái)?shù)據(jù)給 JSP 并展示給用戶宏邮。

Model2 模式下還存在很多問題泽示,Model2的抽象和封裝程度還遠(yuǎn)遠(yuǎn)不夠,使用Model2進(jìn)行開發(fā)時(shí)不可避免地會(huì)重復(fù)造輪子蜜氨,這就大大降低了程序的可維護(hù)性和復(fù)用性械筛。于是很多JavaWeb開發(fā)相關(guān)的 MVC 框架應(yīng)運(yùn)而生比如Struts2,但是 Struts2 比較笨重飒炎。隨著 Spring 輕量級(jí)開發(fā)框架的流行埋哟,Spring 生態(tài)圈出現(xiàn)了 Spring MVC 框架, Spring MVC 是當(dāng)前最優(yōu)秀的 MVC 框架郎汪。相比于 Struts2 赤赊, Spring MVC 使用更加簡(jiǎn)單和方便,開發(fā)效率更高煞赢,并且 Spring MVC 運(yùn)行速度更快抛计。

MVC 是一種設(shè)計(jì)模式,Spring MVC 是一款很優(yōu)秀的 MVC 框架。Spring MVC 可以幫助我們進(jìn)行更簡(jiǎn)潔的Web層的開發(fā)耕驰,并且它天生與 Spring 框架集成爷辱。Spring MVC 下我們一般把后端項(xiàng)目分為 Service層(處理業(yè)務(wù))录豺、Dao層(數(shù)據(jù)庫(kù)操作)朦肘、Entity層(實(shí)體類)、Controller層(控制層双饥,返回?cái)?shù)據(jù)給前臺(tái)頁(yè)面)媒抠。

Spring MVC 的簡(jiǎn)單原理圖如下:

6.2 SpringMVC 工作原理了解嗎?

原理如下圖所示:

SpringMVC運(yùn)行原理

上圖的一個(gè)筆誤的小問題:Spring MVC 的入口函數(shù)也就是前端控制器 DispatcherServlet 的作用是接收請(qǐng)求,響應(yīng)結(jié)果咏花。

流程說明(重要):

  1. 客戶端(瀏覽器)發(fā)送請(qǐng)求趴生,直接請(qǐng)求到 DispatcherServlet阀趴。
  2. DispatcherServlet 根據(jù)請(qǐng)求信息調(diào)用 HandlerMapping,解析請(qǐng)求對(duì)應(yīng)的 Handler苍匆。
  3. 解析到對(duì)應(yīng)的 Handler(也就是我們平常說的 Controller 控制器)后刘急,開始由 HandlerAdapter 適配器處理。
  4. HandlerAdapter 會(huì)根據(jù) Handler來調(diào)用真正的處理器來處理請(qǐng)求浸踩,并處理相應(yīng)的業(yè)務(wù)邏輯叔汁。
  5. 處理器處理完業(yè)務(wù)后,會(huì)返回一個(gè) ModelAndView 對(duì)象检碗,Model 是返回的數(shù)據(jù)對(duì)象据块,View 是個(gè)邏輯上的 View
  6. ViewResolver 會(huì)根據(jù)邏輯 View 查找實(shí)際的 View折剃。
  7. DispaterServlet 把返回的 Model 傳給 View(視圖渲染)另假。
  8. View 返回給請(qǐng)求者(瀏覽器)

7. Spring 框架中用到了哪些設(shè)計(jì)模式?

關(guān)于下面一些設(shè)計(jì)模式的詳細(xì)介紹怕犁,可以看筆主前段時(shí)間的原創(chuàng)文章《面試官:“談?wù)凷pring中都用到了那些設(shè)計(jì)模式?”边篮。》 奏甫。

  • 工廠設(shè)計(jì)模式 : Spring使用工廠模式通過 BeanFactory苟耻、ApplicationContext 創(chuàng)建 bean 對(duì)象。
  • 代理設(shè)計(jì)模式 : Spring AOP 功能的實(shí)現(xiàn)扶檐。
  • 單例設(shè)計(jì)模式 : Spring 中的 Bean 默認(rèn)都是單例的凶杖。
  • 模板方法模式 : Spring 中 jdbcTemplatehibernateTemplate 等以 Template 結(jié)尾的對(duì)數(shù)據(jù)庫(kù)操作的類款筑,它們就使用到了模板模式智蝠。
  • 包裝器設(shè)計(jì)模式 : 我們的項(xiàng)目需要連接多個(gè)數(shù)據(jù)庫(kù),而且不同的客戶在每次訪問中根據(jù)需要會(huì)去訪問不同的數(shù)據(jù)庫(kù)奈梳。這種模式讓我們可以根據(jù)客戶的需求能夠動(dòng)態(tài)切換不同的數(shù)據(jù)源杈湾。
  • 觀察者模式: Spring 事件驅(qū)動(dòng)模型就是觀察者模式很經(jīng)典的一個(gè)應(yīng)用。
  • 適配器模式 :Spring AOP 的增強(qiáng)或通知(Advice)使用到了適配器模式攘须、spring MVC 中也是用到了適配器模式適配Controller漆撞。
  • ......

8. Spring 事務(wù)

8.1 Spring 管理事務(wù)的方式有幾種?

  1. 編程式事務(wù)于宙,在代碼中硬編碼浮驳。(不推薦使用)
  2. 聲明式事務(wù),在配置文件中配置(推薦使用)

聲明式事務(wù)又分為兩種:

  1. 基于XML的聲明式事務(wù)
  2. 基于注解的聲明式事務(wù)

8.2 Spring 事務(wù)中的隔離級(jí)別有哪幾種?

TransactionDefinition 接口中定義了五個(gè)表示隔離級(jí)別的常量:

  • TransactionDefinition.ISOLATION_DEFAULT: 使用后端數(shù)據(jù)庫(kù)默認(rèn)的隔離級(jí)別捞魁,Mysql 默認(rèn)采用的 REPEATABLE_READ隔離級(jí)別 Oracle 默認(rèn)采用的 READ_COMMITTED隔離級(jí)別.
  • TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔離級(jí)別至会,允許讀取尚未提交的數(shù)據(jù)變更,可能會(huì)導(dǎo)致臟讀谱俭、幻讀或不可重復(fù)讀
  • TransactionDefinition.ISOLATION_READ_COMMITTED: 允許讀取并發(fā)事務(wù)已經(jīng)提交的數(shù)據(jù)奉件,可以阻止臟讀宵蛀,但是幻讀或不可重復(fù)讀仍有可能發(fā)生
  • TransactionDefinition.ISOLATION_REPEATABLE_READ: 對(duì)同一字段的多次讀取結(jié)果都是一致的,除非數(shù)據(jù)是被本身事務(wù)自己所修改县貌,可以阻止臟讀和不可重復(fù)讀术陶,但幻讀仍有可能發(fā)生。
  • TransactionDefinition.ISOLATION_SERIALIZABLE: 最高的隔離級(jí)別煤痕,完全服從ACID的隔離級(jí)別瞳别。所有的事務(wù)依次逐個(gè)執(zhí)行,這樣事務(wù)之間就完全不可能產(chǎn)生干擾杭攻,也就是說祟敛,該級(jí)別可以防止臟讀、不可重復(fù)讀以及幻讀兆解。但是這將嚴(yán)重影響程序的性能馆铁。通常情況下也不會(huì)用到該級(jí)別。

8.3 Spring 事務(wù)中哪幾種事務(wù)傳播行為?

支持當(dāng)前事務(wù)的情況:

  • TransactionDefinition.PROPAGATION_REQUIRED: 如果當(dāng)前存在事務(wù)锅睛,則加入該事務(wù)埠巨;如果當(dāng)前沒有事務(wù),則創(chuàng)建一個(gè)新的事務(wù)现拒。
  • TransactionDefinition.PROPAGATION_SUPPORTS: 如果當(dāng)前存在事務(wù)辣垒,則加入該事務(wù);如果當(dāng)前沒有事務(wù)印蔬,則以非事務(wù)的方式繼續(xù)運(yùn)行勋桶。
  • TransactionDefinition.PROPAGATION_MANDATORY: 如果當(dāng)前存在事務(wù),則加入該事務(wù)侥猬;如果當(dāng)前沒有事務(wù)例驹,則拋出異常。(mandatory:強(qiáng)制性)

不支持當(dāng)前事務(wù)的情況:

  • TransactionDefinition.PROPAGATION_REQUIRES_NEW: 創(chuàng)建一個(gè)新的事務(wù)退唠,如果當(dāng)前存在事務(wù)鹃锈,則把當(dāng)前事務(wù)掛起。
  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事務(wù)方式運(yùn)行瞧预,如果當(dāng)前存在事務(wù)屎债,則把當(dāng)前事務(wù)掛起。
  • TransactionDefinition.PROPAGATION_NEVER: 以非事務(wù)方式運(yùn)行垢油,如果當(dāng)前存在事務(wù)盆驹,則拋出異常。

其他情況:

  • TransactionDefinition.PROPAGATION_NESTED: 如果當(dāng)前存在事務(wù)秸苗,則創(chuàng)建一個(gè)事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來運(yùn)行召娜;如果當(dāng)前沒有事務(wù)运褪,則該取值等價(jià)于TransactionDefinition.PROPAGATION_REQUIRED惊楼。

8.4 @Transactional(rollbackFor = Exception.class)注解了解嗎玖瘸?

我們知道:Exception分為運(yùn)行時(shí)異常RuntimeException和非運(yùn)行時(shí)異常。事務(wù)管理對(duì)于企業(yè)應(yīng)用來說是至關(guān)重要的檀咙,即使出現(xiàn)異常情況雅倒,它也可以保證數(shù)據(jù)的一致性。

當(dāng)@Transactional注解作用于類上時(shí)弧可,該類的所有 public 方法將都具有該類型的事務(wù)屬性蔑匣,同時(shí),我們也可以在方法級(jí)別使用該標(biāo)注來覆蓋類級(jí)別的定義棕诵。如果類或者方法加了這個(gè)注解裁良,那么這個(gè)類里面的方法拋出異常,就會(huì)回滾校套,數(shù)據(jù)庫(kù)里面的數(shù)據(jù)也會(huì)回滾价脾。

@Transactional注解中如果不配置rollbackFor屬性,那么事務(wù)只會(huì)在遇到RuntimeException的時(shí)候才會(huì)回滾,加上rollbackFor=Exception.class,可以讓事務(wù)在遇到非運(yùn)行時(shí)異常時(shí)也回滾。

關(guān)于 @Transactional注解推薦閱讀的文章:

9. JPA

9.1 如何使用JPA在數(shù)據(jù)庫(kù)中非持久化一個(gè)字段笛匙?

假如我們有有下面一個(gè)類:

Entity(name="USER")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private Long id;

    @Column(name="USER_NAME")
    private String userName;

    @Column(name="PASSWORD")
    private String password;

    private String secrect;

}

如果我們想讓secrect 這個(gè)字段不被持久化侨把,也就是不被數(shù)據(jù)庫(kù)存儲(chǔ)怎么辦?我們可以采用下面幾種方法:

static String transient1; // not persistent because of static
final String transient2 = “Satish”; // not persistent because of final
transient String transient3; // not persistent because of transient
@Transient
String transient4; // not persistent because of @Transient

一般使用后面兩種方式比較多妹孙,我個(gè)人使用注解的方式比較多秋柄。

參考

作者:Snailclimb
鏈接:Spring常見問題總結(jié)
來源:github

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蠢正,一起剝皮案震驚了整個(gè)濱河市骇笔,隨后出現(xiàn)的幾起案子嚣崭,更是在濱河造成了極大的恐慌蜘拉,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件有鹿,死亡現(xiàn)場(chǎng)離奇詭異旭旭,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)葱跋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門持寄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人娱俺,你說我怎么就攤上這事稍味。” “怎么了荠卷?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵模庐,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我油宜,道長(zhǎng)掂碱,這世上最難降的妖魔是什么怜姿? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮疼燥,結(jié)果婚禮上沧卢,老公的妹妹穿的比我還像新娘。我一直安慰自己醉者,他們只是感情好但狭,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著撬即,像睡著了一般立磁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上剥槐,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天息罗,我揣著相機(jī)與錄音,去河邊找鬼才沧。 笑死迈喉,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的温圆。 我是一名探鬼主播挨摸,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼岁歉!你這毒婦竟也來了得运?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤锅移,失蹤者是張志新(化名)和其女友劉穎熔掺,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體非剃,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡置逻,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了备绽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片券坞。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肺素,靈堂內(nèi)的尸體忽然破棺而出恨锚,到底是詐尸還是另有隱情,我是刑警寧澤倍靡,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布猴伶,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏他挎。R本人自食惡果不足惜筝尾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望雇盖。 院中可真熱鬧忿等,春花似錦栖忠、人聲如沸崔挖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)狸相。三九已至,卻和暖如春捐川,著一層夾襖步出監(jiān)牢的瞬間脓鹃,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工古沥, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瘸右,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓岩齿,卻偏偏與公主長(zhǎng)得像太颤,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子盹沈,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容