提示:文章寫(xiě)完后,目錄可以自動(dòng)生成,如何生成可參考右邊的幫助文檔
前言
本文主要記錄spring的單例bean、切面編程AOP、spring事務(wù)、循環(huán)依賴(lài)、常見(jiàn)注解等
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
一、框架知識(shí)分布
二、Spring
1. spring-單例bean
① 問(wèn)題引入
Spring框架中的bean是單例的
singleton :bean在每個(gè)Spring IOC容器中只有一個(gè)實(shí)例。
prototype:一個(gè)bean的定義可以有多個(gè)實(shí)例。
② 單例bean是線(xiàn)程安全的嗎
count是可修改的成員變量需要考慮線(xiàn)程安全
userService是無(wú)法修改的成員變量不需要考慮線(xiàn)程安全
③ 問(wèn)題總結(jié)
④ 實(shí)戰(zhàn)面試
2. spring-AOP
① 問(wèn)題引入
AOP稱(chēng)為面向切面編程,用于將那些與業(yè)務(wù)無(wú)關(guān),但卻對(duì)多個(gè)對(duì)象產(chǎn)生影響的公共行為和邏輯,抽取并封裝為一個(gè)可重用的模塊,這個(gè)模塊被命名為“切面”(Aspect),減少系統(tǒng)中的重復(fù)代碼,降低模塊間的耦合度,同時(shí)提高了系統(tǒng)的可維護(hù)性。
常見(jiàn)的AOP使用場(chǎng)景:
1.記錄操作日志(每一個(gè)service記錄操作)
2.緩存處理(業(yè)務(wù)加緩存,寫(xiě)在AOP的切面攔截需要添加緩存的業(yè)務(wù)方法)
3.Spring中內(nèi)置的事務(wù)處理
② AOP記錄操作日志
獲取請(qǐng)求的用戶(hù)名、請(qǐng)求方式、訪(fǎng)問(wèn)地址、模塊名稱(chēng)、登錄ip、操作時(shí)間,記錄到數(shù)據(jù)庫(kù)的日志表中,如下圖所示:
后臺(tái)有四個(gè)請(qǐng)求接口,需要記錄操作日志,使用AOP提供的環(huán)繞通知做一個(gè)切面,相當(dāng)于一個(gè)通過(guò)的代碼,遇到請(qǐng)求的時(shí)候就可以執(zhí)行這段代碼。
代碼解釋?zhuān)篽ttps://zhuanlan.zhihu.com/p/596205936?utm_id=0
③ Spring事務(wù)如何實(shí)現(xiàn)的
Spring支持編程式事務(wù)管理和聲明式事務(wù)管理兩種方式。
- 編程式事務(wù)控制:需使用TransactionTemplate來(lái)進(jìn)行實(shí)現(xiàn),對(duì)業(yè)務(wù)代碼有侵入性,項(xiàng)目中很少使用
- 聲明式事務(wù)管理:聲明式事務(wù)管理建立在AOP之上的。其本質(zhì)是通過(guò)AOP功能**,對(duì)方法前后進(jìn)行攔截**,將事務(wù)處理的功能編織到攔截的方法中,也就是在目標(biāo)方法開(kāi)始之前加入一個(gè)事務(wù),在執(zhí)行完目標(biāo)方法之后根據(jù)執(zhí)行情況提交或者回滾事務(wù)。(常用)
④ 問(wèn)題總結(jié)
3. Spring-事務(wù)失效的場(chǎng)景
① 問(wèn)題引入
對(duì)spring框架的深入理解、復(fù)雜業(yè)務(wù)的編碼經(jīng)驗(yàn)
- 異常捕獲處理
- 拋出檢查異常
- 非public方法
② 情況一:異常捕獲處理
轉(zhuǎn)賬的代碼中出現(xiàn)一個(gè)異常,由于這個(gè)異常會(huì)被try-catch捕獲卻沒(méi)有拋出,所以可能導(dǎo)致事務(wù)失效(如果異常沒(méi)有被捕獲,就會(huì)發(fā)生事務(wù)回滾)
原因分析: 事務(wù)通知只有捉到了目標(biāo)拋出的異常,才能進(jìn)行后續(xù)的回滾處理,如果目標(biāo)自己處理掉異常,事務(wù)通知無(wú)法知悉
解決方法: 在catch塊添加throw new RuntimeException(e)拋出
③ 情況二:拋出檢查異常
系統(tǒng)找不到指定文件,拋出一個(gè)檢查異常
原因分析: Spring 默認(rèn)只會(huì)回滾非檢查異常
解決方法: 配置rollbackFor屬性Transactional(rollbackFor=Exception.class)
,一旦出現(xiàn)異常都會(huì)被事務(wù)控制
④ 非public方法導(dǎo)致事務(wù)失效
方法沒(méi)有用public
原因分析: Spring為方法創(chuàng)建代理、添加事務(wù)通知、前提條件都是該方法是public的
解決方法: 方法改為public
⑤ 問(wèn)題總結(jié)
4. Spring-bean的生命周期(難)
① 問(wèn)題引入
Spring容器是如何管理和創(chuàng)建bean實(shí)例
方便調(diào)試和解決問(wèn)題
② BeanDefinition(Bean的定義信息)
Spring容器在進(jìn)行實(shí)例化時(shí),會(huì)將xml配置的<bean>
的信息封裝成一個(gè)BeanDefinition對(duì)象,Spring根據(jù)BeanDefinition來(lái)創(chuàng)建Bean對(duì)象,里面有很多的屬性用來(lái)描述Bean
③ 問(wèn)題總結(jié)
5. Spring-bean的循環(huán)依賴(lài)
① 問(wèn)題引入
在創(chuàng)建A對(duì)象的同時(shí)需要使用的B對(duì)象,在創(chuàng)建B對(duì)象的同時(shí)需要使用到A對(duì)象
② Spring的循環(huán)依賴(lài)
Spring解決循環(huán)依賴(lài)是通過(guò)三級(jí)緩存,對(duì)應(yīng)的三級(jí)緩存如下所示:
如果要想打破循環(huán)依賴(lài),就需要一個(gè)中間人的參與,這個(gè)中間人就是二級(jí)緩存。
一級(jí)和二級(jí)緩存可以解決一般對(duì)象的循環(huán)依賴(lài)
代理對(duì)象需要用到三級(jí)緩存
構(gòu)造方法注入產(chǎn)生的循環(huán)依賴(lài)問(wèn)題,使用延遲加載解決問(wèn)題
③ 問(wèn)題總結(jié)
三、SpringMVC
1. SpringMVC-執(zhí)行流程
① 問(wèn)題引入
Springmvc的執(zhí)行流程是這個(gè)框架最核心的內(nèi)容
- 視圖階段(老舊JSP等)
- 前后端分離階段(接口開(kāi)發(fā),異步)
② 視圖階段(JSP)
重要的組件:前端控制器、處理器映射器、處理器適配器、視圖解析器
③ 前后端分離階段(接口開(kāi)發(fā),異步)
④ 問(wèn)題總結(jié)
四、SpringBoot
1. springboot-自動(dòng)配置
① 問(wèn)題引入
自動(dòng)配置主要依賴(lài)于@SpringBootApplication
注解,其中還包含了三個(gè)注解@SpringBootConfiguration
:該注解與@Configuration注解作用相同,用來(lái)聲明當(dāng)前也是
個(gè)配置類(lèi)。@ComponentScan
:組件掃描,默認(rèn)掃描當(dāng)前引導(dǎo)類(lèi)所在包及其子包。@EnableAutoConfiguration
: SpringBoot實(shí)現(xiàn)自動(dòng)化配置的核心注解。
② 問(wèn)題總結(jié)
五、Spring-框架中常見(jiàn)的注解
1. spring常見(jiàn)的注解
2. springMVC常見(jiàn)注解
3.springboot常見(jiàn)注解
六、Mybatis
1. Mybatis-執(zhí)行流程
① 問(wèn)題引入
- 理解了各個(gè)組件的關(guān)系
- Sql的執(zhí)行過(guò)程(參數(shù)映射、sql解析、執(zhí)行和結(jié)果處理)
② Mybatis執(zhí)行流程
2. Mybatis支持延遲加載
① 問(wèn)題引入
② 立即加載
查詢(xún)用戶(hù)信息的同時(shí)也可以查詢(xún)到相關(guān)訂單信息
UserMapper:
OrderMapper:
UserTest.java 打印輸出用戶(hù)信息
執(zhí)行結(jié)果:
③ 延遲加載
fetchType="lazy"
開(kāi)啟局部延遲加載
UserMapper:
UserTest.java 打印輸出用戶(hù)信息
執(zhí)行結(jié)果:先調(diào)用查詢(xún)用戶(hù)信息,然后因?yàn)檎{(diào)用了getOrderList(),所以還執(zhí)行了查找對(duì)應(yīng)訂單的sql
在配置文件中開(kāi)啟全局延遲加載:
延遲加載的原理
- 使用CGLIB創(chuàng)建目標(biāo)對(duì)象的代理對(duì)象
- 調(diào)用目標(biāo)方法user.getOrderList)時(shí),進(jìn)入攔截器invoke方法,發(fā)現(xiàn)user.getOrderList()是null值,執(zhí)行sql查詢(xún)order列表3.把order查詢(xún)上來(lái),然后調(diào)用user.setOrderList(List orderList),接著完成user.getOrderList()方法的調(diào)用
④ 問(wèn)題總結(jié)
3. Mybatis-一級(jí)二級(jí)緩存
① 問(wèn)題引入
● 本地緩存:基于PerpetualCache,本質(zhì)是一個(gè)HashMap
● 一級(jí)緩存:作用域是session級(jí)別
● 二級(jí)緩存:作用域是namespace和mapper的作用域,不依賴(lài)于session
② 一級(jí)緩存
一級(jí)緩存:基于PerpetualCache的 HashMap本地緩存,其存儲(chǔ)作用域?yàn)镾ession,當(dāng)Session進(jìn)行flush或close之后,該Session中的所有Cache就將清空,默認(rèn)打開(kāi)一級(jí)緩存
因?yàn)檫@兩個(gè)都是查詢(xún)的同一個(gè)id的用戶(hù)信息,所以第二次查詢(xún)的時(shí)候直接在緩存中取,而不需要再次執(zhí)行SQL語(yǔ)句
③ 二級(jí)緩存
二級(jí)緩存是基于namespace和mapper的作用域起作用的,不是依賴(lài)于SQL session,默認(rèn)也是采用PerpetualCache,HashMap存儲(chǔ)(默認(rèn)關(guān)閉)
開(kāi)啟二級(jí)緩存的兩個(gè)步驟:
-
全局配置文件
-
映射文件:使用
<cache/>
標(biāo)簽讓當(dāng)前mapper生效二級(jí)緩存 -
執(zhí)行結(jié)果:只調(diào)用了一次SQL
注意事項(xiàng):
- 對(duì)于緩存數(shù)據(jù)更新機(jī)制,當(dāng)某一個(gè)作用域(一級(jí)緩存Session/二級(jí)緩存Namespaces)的進(jìn)行了新增、修改、刪除操作后,默認(rèn)該作用域下所有select中的緩存將被clear
- 二級(jí)緩存需要緩存的數(shù)據(jù)實(shí)現(xiàn)Serializable接口
- 只有會(huì)話(huà)提交或者關(guān)閉以后,一級(jí)緩存中的數(shù)據(jù)才會(huì)轉(zhuǎn)移到二級(jí)緩存中、
④ 問(wèn)題總結(jié)
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-733662.html
引用說(shuō)明
https://www.bilibili.com/video/BV1yT411H7YK?p=35&vd_source=98092b0aee05ae7c890b09fe07f13df4文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-733662.html
到了這里,關(guān)于Java開(kāi)發(fā)之框架(spring、springmvc、springboot、mybatis)【面試篇 完結(jié)版】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!