Spring常見問題總結(jié)

此文章來源于SnailClimb @https://mp.weixin.qq.com/s/yaY3gcP0aEp7w-mUwl1yCQ

IOC

IoC(Inverse of Control:控制反轉(zhuǎn))是一種設(shè)計思想活逆,就是 將原本在程序中手動創(chuàng)建對象的控制權(quán),交由Spring框架來管理。 IoC 在其他語言中也有應(yīng)用缩歪,并非 Spirng 特有。 IoC 容器是 Spring 用來實現(xiàn) IoC 的載體, IoC 容器實際上就是個Map(key,value),Map 中存放的是各種對象殴俱。

將對象之間的相互依賴關(guān)系交給 IoC 容器來管理,并由 IoC 容器完成對象的注入枚抵。這樣可以很大程度上簡化應(yīng)用的開發(fā)线欲,把應(yīng)用從復(fù)雜的依賴關(guān)系中解放出來。 IoC 容器就像是一個工廠一樣汽摹,當(dāng)我們需要創(chuàng)建一個對象的時候李丰,只需要配置好配置文件/注解即可,完全不用考慮對象是如何被創(chuàng)建出來的逼泣。 在實際項目中一個 Service 類可能有幾百甚至上千個類作為它的底層趴泌,假如我們需要實例化這個 Service舟舒,你可能要每次都要搞清這個 Service 所有底層類的構(gòu)造函數(shù),這可能會把人逼瘋嗜憔。如果利用 IoC 的話秃励,你只需要配置好,然后在需要的地方引用就行了吉捶,這大大增加了項目的可維護(hù)性且降低了開發(fā)難度夺鲜。

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

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

image.png

IoC源碼閱讀 https://javadoop.com/post/spring-ioc

AOP

Spring AOP就是基于動態(tài)代理的,如果要代理的對象珊拼,實現(xiàn)了某個接口食呻,那么Spring AOP會使用JDK Proxy,去創(chuàng)建代理對象澎现,而對于沒有實現(xiàn)接口的對象仅胞,就無法使用 JDK Proxy 去進(jìn)行代理了,這時候Spring AOP會使用Cglib 昔头,這時候Spring AOP會使用 Cglib 生成一個被代理對象的子類來作為代理饼问,如下圖所示:


image.png

當(dāng)然你也可以使用 AspectJ ,Spring AOP 已經(jīng)集成了AspectJ 影兽,AspectJ 應(yīng)該算的上是 Java 生態(tài)系統(tǒng)中最完整的 AOP 框架了揭斧。
使用 AOP 之后我們可以把一些通用功能抽象出來,在需要用到的地方直接使用即可峻堰,這樣大大簡化了代碼量讹开。我們需要增加新功能時也方便,這樣也提高了系統(tǒng)擴(kuò)展性捐名。日志功能旦万、事務(wù)管理等等場景都用到了 AOP 。

Spring AOP 和 AspectJ AOP 有什么區(qū)別镶蹋?

Spring AOP 屬于運行時增強(qiáng)成艘,而 AspectJ 是編譯時增強(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 相對來說更簡單,
如果我們的切面比較少婶熬,那么兩者性能差異不大剑勾。但是埃撵,當(dāng)切面太多的話,最好選擇 AspectJ 虽另,它比Spring AOP 快很多暂刘。

Spring 中的 bean 生命周期
這部分網(wǎng)上有很多文章都講到了,下面的內(nèi)容整理自:https://yemengying.com/2016/07/14/spring-bean-life-cycle/ 洲赵,除了這篇文章鸳惯,再推薦一篇很不錯的文章 :https://www.cnblogs.com/zrtqsk/p/3735273.html

  • Bean 容器找到配置文件中 Spring Bean 的定義叠萍。
  • Bean 容器利用 Java Reflection API 創(chuàng)建一個Bean的實例芝发。
  • 如果涉及到一些屬性值 利用 set()方法設(shè)置一些屬性值。
  • 如果 Bean 實現(xiàn)了 BeanNameAware 接口苛谷,調(diào)用 setBeanName()方法辅鲸,傳入Bean的名字。
  • 如果 Bean 實現(xiàn)了 BeanClassLoaderAware 接口腹殿,調(diào)用 setBeanClassLoader()方法独悴,傳入 ClassLoader對象的實例。
  • 如果Bean實現(xiàn)了 BeanFactoryAware 接口锣尉,調(diào)用 setBeanClassLoader()方法刻炒,傳入 ClassLoade r對象的實例。
    與上面的類似自沧,如果實現(xiàn)了其他 *.Aware接口坟奥,就調(diào)用相應(yīng)的方法。
  • 如果有和加載這個 Bean 的 Spring 容器相關(guān)的 BeanPostProcessor 對象拇厢,執(zhí)行postProcessBeforeInitialization() 方法
  • 如果Bean實現(xiàn)了InitializingBean接口爱谁,執(zhí)行afterPropertiesSet()方法。
  • 如果 Bean 在配置文件中的定義包含 init-method 屬性孝偎,執(zhí)行指定的方法访敌。
  • 如果有和加載這個 Bean的 Spring 容器相關(guān)的 BeanPostProcessor 對象,執(zhí)行postProcessAfterInitialization() 方法
  • 當(dāng)要銷毀 Bean 的時候衣盾,如果 Bean 實現(xiàn)了 DisposableBean 接口寺旺,執(zhí)行 destroy() 方法。
  • 當(dāng)要銷毀 Bean 的時候势决,如果 Bean 在配置文件中的定義包含 destroy-method 屬性阻塑,執(zhí)行指定的方法。


    image.png
image.png

Spring 框架中用到了哪些設(shè)計模式
關(guān)于下面一些設(shè)計模式的詳細(xì)介紹徽龟,可以看筆主前段時間的原創(chuàng)文章《面試官:“談?wù)凷pring中都用到了那些設(shè)計模式?”叮姑。》

  • 工廠設(shè)計模式 : Spring使用工廠模式通過 BeanFactory传透、ApplicationContext 創(chuàng)建 bean 對象耘沼。

  • 代理設(shè)計模式 : Spring AOP 功能的實現(xiàn)。

  • 單例設(shè)計模式 : Spring 中的 Bean 默認(rèn)都是單例的朱盐。

  • 模板方法模式 : Spring 中 jdbcTemplate群嗤、hibernateTemplate 等以 Template 結(jié)尾的對數(shù)據(jù)庫操作的類,它們就使用到了模板模式兵琳。

  • 包裝器設(shè)計模式 : 我們的項目需要連接多個數(shù)據(jù)庫狂秘,而且不同的客戶在每次訪問中根據(jù)需要會去訪問不同的數(shù)據(jù)庫。這種模式讓我們可以根據(jù)客戶的需求能夠動態(tài)切換不同的數(shù)據(jù)源躯肌。

  • 觀察者模式: Spring 事件驅(qū)動模型就是觀察者模式很經(jīng)典的一個應(yīng)用者春。

  • 適配器模式 :Spring AOP 的增強(qiáng)或通知(Advice)使用到了適配器模式、spring MVC 中也是用到了適配器模式適配Controller清女。

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

  • 作用對象不同: @Component 注解作用于類,而@Bean注解作用于方法嫡丙。
  • @Component通常是通過類路徑掃描來自動偵測以及自動裝配到Spring容器中(我們可以使用 - - -- @ComponentScan 注解定義要掃描的路徑從中找出標(biāo)識了需要裝配的類自動裝配到 Spring 的 bean 容器中)拴袭。@Bean 注解通常是我們在標(biāo)有該注解的方法中定義產(chǎn)生這個 bean,@Bean告訴了Spring這是某個類的示例,當(dāng)我需要用它的時候還給我曙博。
  • @Bean 注解比 Component 注解的自定義性更強(qiáng)拥刻,而且很多地方我們只能通過 @Bean 注解來注冊bean。比如當(dāng)我們引用第三方庫中的類需要裝配到 Spring容器時父泳,則只能通過 @Bean來實現(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>

下面這個例子是通過 @Component 無法實現(xiàn)的。

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

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

TransactionDefinition 接口中定義了五個表示隔離級別的常量:

  • TransactionDefinition.ISOLATION_DEFAULT: 使用后端數(shù)據(jù)庫默認(rèn)的隔離級別尘吗,Mysql 默認(rèn)采用的 REPEATABLE_READ隔離級別 Oracle 默認(rèn)采用的 READ_COMMITTED隔離級別.
  • TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔離級別逝她,允許讀取尚未提交的數(shù)據(jù)變更浇坐,可能會導(dǎo)致臟讀睬捶、幻讀或不可重復(fù)讀
  • TransactionDefinition.ISOLATION_READ_COMMITTED: 允許讀取并發(fā)事務(wù)已經(jīng)提交的數(shù)據(jù),可以阻止臟讀近刘,但是幻讀或不可重復(fù)讀仍有可能發(fā)生
  • TransactionDefinition.ISOLATION_REPEATABLE_READ: 對同一字段的多次讀取結(jié)果都是一致的擒贸,除非數(shù)據(jù)是被本身事務(wù)自己所修改,可以阻止臟讀和不可重復(fù)讀觉渴,但幻讀仍有可能發(fā)生介劫。
  • TransactionDefinition.ISOLATION_SERIALIZABLE: 最高的隔離級別,完全服從ACID的隔離級別案淋。所有的事務(wù)依次逐個執(zhí)行座韵,這樣事務(wù)之間就完全不可能產(chǎn)生干擾,也就是說,該級別可以防止臟讀誉碴、不可重復(fù)讀以及幻讀宦棺。但是這將嚴(yán)重影響程序的性能。通常情況下也不會用到該級別黔帕。

Spring 事務(wù)中哪幾種事務(wù)傳播行為?
支持當(dāng)前事務(wù)的情況:

  • TransactionDefinition.PROPAGATION_REQUIRED: 如果當(dāng)前存在事務(wù)代咸,則加入該事務(wù);如果當(dāng)前沒有事務(wù)成黄,則創(chuàng)建一個新的事務(wù)呐芥。

  • TransactionDefinition.PROPAGATION_SUPPORTS: 如果當(dāng)前存在事務(wù),則加入該事務(wù)奋岁;如果當(dāng)前沒有事務(wù)思瘟,則以非事務(wù)的方式繼續(xù)運行。

  • TransactionDefinition.PROPAGATION_MANDATORY: 如果當(dāng)前存在事務(wù)闻伶,則加入該事務(wù)潮太;如果當(dāng)前沒有事務(wù),則拋出異常虾攻。(mandatory:強(qiáng)制性)
    不支持當(dāng)前事務(wù)的情況:

  • TransactionDefinition.PROPAGATION_REQUIRES_NEW: 創(chuàng)建一個新的事務(wù)铡买,如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起霎箍。

  • TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事務(wù)方式運行奇钞,如果當(dāng)前存在事務(wù),則把當(dāng)前事務(wù)掛起漂坏。

  • TransactionDefinition.PROPAGATION_NEVER: 以非事務(wù)方式運行景埃,如果當(dāng)前存在事務(wù),則拋出異常顶别。
    其他情況:

  • TransactionDefinition.PROPAGATION_NESTED: 如果當(dāng)前存在事務(wù)谷徙,則創(chuàng)建一個事務(wù)作為當(dāng)前事務(wù)的嵌套事務(wù)來運行;如果當(dāng)前沒有事務(wù)驯绎,則該取值等價于TransactionDefinition.PROPAGATION_REQUIRED完慧。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市剩失,隨后出現(xiàn)的幾起案子屈尼,更是在濱河造成了極大的恐慌,老刑警劉巖拴孤,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脾歧,死亡現(xiàn)場離奇詭異,居然都是意外死亡演熟,警方通過查閱死者的電腦和手機(jī)鞭执,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人兄纺,你說我怎么就攤上這事免猾。” “怎么了囤热?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵猎提,是天一觀的道長。 經(jīng)常有香客問我旁蔼,道長锨苏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任棺聊,我火速辦了婚禮伞租,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘限佩。我一直安慰自己葵诈,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布祟同。 她就那樣靜靜地躺著作喘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪晕城。 梳的紋絲不亂的頭發(fā)上泞坦,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天,我揣著相機(jī)與錄音砖顷,去河邊找鬼贰锁。 笑死,一個胖子當(dāng)著我的面吹牛滤蝠,可吹牛的內(nèi)容都是我干的豌熄。 我是一名探鬼主播,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼物咳,長吁一口氣:“原來是場噩夢啊……” “哼锣险!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起所森,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤囱持,失蹤者是張志新(化名)和其女友劉穎夯接,沒想到半個月后焕济,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡盔几,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年晴弃,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡上鞠,死狀恐怖际邻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情芍阎,我是刑警寧澤世曾,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站谴咸,受9級特大地震影響轮听,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜岭佳,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一血巍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧珊随,春花似錦述寡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至衩辟,卻和暖如春掀序,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背惭婿。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工不恭, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人财饥。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓换吧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親钥星。 傳聞我的和親對象是個殘疾皇子沾瓦,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

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