1.Spring 兩大核心
控制反轉(IOC)或依賴注入(DI),面向切面編程(AOP)
(1)面向切面編程(AOP)
AOP將哪些與業務無關的,但對多個對象產生一個像的公共行為和邏輯,抽取並封裝為一個可重用的模塊。這個模塊被命名為‘切面’(Aspect),減少系統中的重復代碼,降低了模塊間的耦合,同時提高了系統的可維護性。可用於權限認證、日志,事務處理。
使用場景:
- Transactions 事務
- Cache 緩存
- Synchronization 同步
- Authentioncation 權限
- Context passing 內容傳遞
- Error handing 錯誤處理
- Lazy loading 懶加載
- logging 日志
- Performance optimazation 性能優化
- profilling and monitoring 紀錄跟蹤優化
- Persistence 持久化
- Resource pooling 資源池
- Debugging 調試
AOP實現的關鍵在於 代理模式,AOP代理主要分為靜態代理和動態代理。靜態代理的代表為AspectJ;動態代理則以Spring AOP為代表。
(1)AspectJ是靜態代理的增強,所謂靜態代理,就是AOP框架會在編譯階段生成AOP代理類,因此也稱為編譯時增強,他會在編譯階段將AspectJ(切面)織入到Java字節碼中,運行的時候就是增強之后的AOP對象。
(2)Spring AOP使用的動態代理,所謂的動態代理就是說AOP框架不會去修改字節碼,而是每次運行時在內存中臨時為方法生成一個AOP對象,這個AOP對象包含了目標對象的全部方法,並且在特定的切點做了增強處理,並回調原對象的方法。
Spring AOP中的動態代理主要有兩種方式,JDK動態代理和CGLIB動態代理:
①JDK動態代理只提供接口的代理,不支持類的代理。核心InvocationHandler接口和Proxy類,InvocationHandler 通過invoke()方法反射來調用目標類中的代碼,動態地將橫切邏輯和業務編織在一起;接着,Proxy利用 InvocationHandler動態創建一個符合某一接口的的實例, 生成目標類的代理對象。
②如果代理類沒有實現 InvocationHandler 接口,那么Spring AOP會選擇使用CGLIB來動態代理目標類。CGLIB(Code Generation Library),是一個代碼生成的類庫,可以在運行時動態的生成指定類的一個子類對象,並覆蓋其中特定方法並添加增強代碼,從而實現AOP。CGLIB是通過繼承的方式做的動態代理,因此如果某個類被標記為final,那么它是無法使用CGLIB做動態代理的。
(3)靜態代理與動態代理區別在於生成AOP代理對象的時機不同,相對來說AspectJ的靜態代理方式具有更好的性能,但是AspectJ需要特定的編譯器進行處理,而Spring AOP則無需特定的編譯器處理。
InvocationHandler 的 invoke(Object proxy,Method method,Object[] args):proxy是最終生成的代理實例; method 是被代理目標實例的某個具體方法; args 是被代理目標實例某個方法的具體入參, 在方法反射調用時使用。
(2)控制反轉(IOC)
將需要的對象通過注入的方式來實現對象的調用。調用者可以直接使用該對象的方法
new 一個對象-------------》工廠類------------------》DI
2.Spring的優點
1)降低了組件之間的耦合性,實現了軟件各層之間的解耦
2)對主流框架提供了集成支持,如hibernate,mabatis,SpringMVC,Struts 等,開發者也可以自由選擇 Spring全部或者部分組件
3)Spring屬於低侵入模式,代碼污染極低
4)提供了眾多服務支持,如事務管理,消息隊列等
3.Spring管理事務的方式有幾種方式?
兩種;(1)編程式事務 在代碼中硬編碼
(2)聲明式事務 在配置文件中配置
聲明式事務又分為兩種
基於XML的聲明式事務
基於注解的聲明式事務
4.Spring bean 的作用域
Spring容器中的bean可以分為5個范圍
1) singleton: 范圍默認,這種范圍不管接受到多少個請求,每個容器中只有一個bean的實例,單利的模式 由bean factory自身維護
2)prototype: 為每一個bean請求提供一個實例
3)request : 在請求bean范圍內為每一個我來自客戶端的網絡請求創建一個實例,在請求完成后,bean失效並會被垃圾回收
4)Session;確保每個session中有一個實例,在session過期后,備案會隨之失效
5)global-session:global-session 和Protlet應用相關。當你的應用部署在Portlet容器中工作時,它包含很多Portlet。如果想要聲明讓所有的portlet共用全局的存儲變量的話,那么全局變量需要存儲在global-session中。
5.Spring 中自動裝配的方式有哪些?
1.不用裝配
2.Byname
通過屬性得分名字查找java bean 依賴的對象進行注入。
3.byType
通過屬性的類型查找javaBean依賴的對象進行注入
4.construtor
和 byType一樣,也是通過類型查找並依賴對象。與ByType的區別在於它不是通過Setter方法注入,而是通過構造方法注入
5.autodetect
在 byType和construts之間自動的選擇注入方式
6.default 由上級標簽<beans>的default-autowrie屬性確定
6.Spring 框架中都用到了哪些設計模式?
(1)工廠模式:BeanFactory就是簡單工廠模式的體現,用來創建對象的實例;
(2)單例模式:Bean默認為單例模式。
(3)代理模式:Spring的AOP功能用到了JDK的動態代理和CGLIB字節碼生成技術;
(4)模板方法:用來解決代碼重復的問題。比如. RestTemplate, JmsTemplate, JpaTemplate。
(5)觀察者模式:定義對象鍵一種一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴於它的對象都會得到通知被制動更新,如Spring中listener的實現--ApplicationListener。
7.Spring事務的實現方式和實現原理:
Spring事務的本質其實就是數據庫對事務的支持,沒有數據庫的事務支持,spring是無法提供事務功能的。真正的數據庫層的事務提交和回滾是通過binlog或者redo log實現的。
(1)Spring事務的種類:
spring支持編程式事務管理和聲明式事務管理兩種方式:
①編程式事務管理使用TransactionTemplate。
②聲明式事務管理建立在AOP之上的。其本質是通過AOP功能,對方法前后進行攔截,將事務處理的功能編織到攔截的方法中,也就是在目標方法開始之前加入一個事務,在執行完目標方法之后根據執行情況提交或者回滾事務。
聲明式事務最大的優點就是不需要在業務邏輯代碼中摻雜事務管理的代碼,只需在配置文件中做相關的事務規則聲明或通過@Transactional注解的方式,便可以將事務規則應用到業務邏輯中。
聲明式事務管理要優於編程式事務管理,這正是spring倡導的非侵入式的開發方式,使業務代碼不受污染,只要加上注解就可以獲得完全的事務支持。唯一不足地方是,最細粒度只能作用到方法級別,無法做到像編程式事務那樣可以作用到代碼塊級別。
(2)spring的事務傳播行為:
spring事務的傳播行為說的是,當多個事務同時存在的時候,spring如何處理這些事務的行為。
① PROPAGATION_REQUIRED:如果當前沒有事務,就創建一個新事務,如果當前存在事務,就加入該事務,該設置是最常用的設置。
② PROPAGATION_SUPPORTS:支持當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就以非事務執行。‘
③ PROPAGATION_MANDATORY:支持當前事務,如果當前存在事務,就加入該事務,如果當前不存在事務,就拋出異常。
④ PROPAGATION_REQUIRES_NEW:創建新事務,無論當前存不存在事務,都創建新事務。
⑤ PROPAGATION_NOT_SUPPORTED:以非事務方式執行操作,如果當前存在事務,就把當前事務掛起。
⑥ PROPAGATION_NEVER:以非事務方式執行,如果當前存在事務,則拋出異常。
⑦ PROPAGATION_NESTED:如果當前存在事務,則在嵌套事務內執行。如果當前沒有事務,則按REQUIRED屬性執行。
(3)Spring中的隔離級別:
① ISOLATION_DEFAULT:這是個 PlatfromTransactionManager 默認的隔離級別,使用數據庫默認的事務隔離級別。
② ISOLATION_READ_UNCOMMITTED:讀未提交,允許另外一個事務可以看到這個事務未提交的數據。
③ ISOLATION_READ_COMMITTED:讀已提交,保證一個事務修改的數據提交后才能被另一事務讀取,而且能看到該事務對已有記錄的更新。
④ ISOLATION_REPEATABLE_READ:可重復讀,保證一個事務修改的數據提交后才能被另一事務讀取,但是不能看到該事務對已有記錄的更新。
⑤ ISOLATION_SERIALIZABLE:一個事務在執行的過程中完全看不到其他事務對數據庫所做的更新。
8、解釋一下Spring AOP里面的幾個名詞:
(1)切面(Aspect):被抽取的公共模塊,可能會橫切多個對象。 在Spring AOP中,切面可以使用通用類(基於模式的風格) 或者在普通類中以 @AspectJ 注解來實現。
(2)連接點(Join point):指方法,在Spring AOP中,一個連接點 總是 代表一個方法的執行。
(3)通知(Advice):在切面的某個特定的連接點(Join point)上執行的動作。通知有各種類型,其中包括“around”、“before”和“after”等通知。許多AOP框架,包括Spring,都是以攔截器做通知模型, 並維護一個以連接點為中心的攔截器鏈。
(4)切入點(Pointcut):切入點是指 我們要對哪些Join point進行攔截的定義。通過切入點表達式,指定攔截的方法,比如指定攔截add*、search*。
(5)引入(Introduction):(也被稱為內部類型聲明(inter-type declaration))。聲明額外的方法或者某個類型的字段。Spring允許引入新的接口(以及一個對應的實現)到任何被代理的對象。例如,你可以使用一個引入來使bean實現 IsModified 接口,以便簡化緩存機制。
(6)目標對象(Target Object): 被一個或者多個切面(aspect)所通知(advise)的對象。也有人把它叫做 被通知(adviced) 對象。 既然Spring AOP是通過運行時代理實現的,這個對象永遠是一個 被代理(proxied) 對象。
(7)織入(Weaving):指把增強應用到目標對象來創建新的代理對象的過程。Spring是在運行時完成織入。
切入點(pointcut)和連接點(join point)匹配的概念是AOP的關鍵,這使得AOP不同於其它僅僅提供攔截功能的舊技術。 切入點使得定位通知(advice)可獨立於OO層次。 例如,一個提供聲明式事務管理的around通知可以被應用到一組橫跨多個對象中的方法上(例如服務層的所有業務操作)
9.Spring通知有哪些類型?
(1)前置通知(Before advice):在某連接點(join point)之前執行的通知,但這個通知不能阻止連接點前的執行(除非它拋出一個異常)。
(2)返回后通知(After returning advice):在某連接點(join point)正常完成后執行的通知:例如,一個方法沒有拋出任何異常,正常返回。
(3)拋出異常后通知(After throwing advice):在方法拋出異常退出時執行的通知。
(4)后通知(After (finally) advice):當某連接點退出的時候執行的通知(不論是正常返回還是異常退出)。
(5)環繞通知(Around Advice):包圍一個連接點(join point)的通知,如方法調用。這是最強大的一種通知類型。 環繞通知可以在方法調用前后完成自定義的行為。它也會選擇是否繼續執行連接點或直接返回它們自己的返回值或拋出異常來結束執行。 環繞通知是最常用的一種通知類型。大部分基於攔截的AOP框架,例如Nanning和JBoss4,都只提供環繞通知。
同一個aspect,不同advice的執行順序:
①沒有異常情況下的執行順序:
around before advice
before advice
target method 執行
around after advice
after advice
afterReturning
②有異常情況下的執行順序:
around before advice
before advice
target method 執行
around after advice
after advice
afterThrowing:異常發生
java.lang.RuntimeException: 異常發生
原文鏈接:https://blog.csdn.net/a745233700/article/details/80959716