1.Spring它到底是什么?
Spring是一個開源的Java應用程序開發框架,為了解決企業應用開發的復雜性而創建的。
??在spring中,它會認為一切Java類都是資源,而資源就是Bean,容納這些Bean是Spring所提供的IoC(Inversion of Control)容器。Spring框架除了幫我們管理對象及其依賴關系(IoC),還提供像通用日志記錄、性能統計、安全控制、異常處理等面向切面的能力(AOP),還能幫我管理最頭疼的數據庫事務,提供與第三方數據訪問框架集成(如Hibernate、JPA),與各種Java EE技術整合(如Java Mail、任務調度等等),提供一套自己的web層框架Spring MVC、而且還能非常簡單的與第三方web框架集成。
2.IoC它是一種思想
??IoC—Inversion of Control,即“控制反轉”,是一種設計思想。這樣的思想是源自于生活的,其核心就是資源不由使用資源的雙方管理,而由不使用資源的第三方管理。例如,我們每天使用的支付寶、微信支付等支付體系就可以說是一個龐大的IoC容器。
??DI(依賴注入)其實就是對IoC設計思想的具體實現。IoC主要的實現方式有兩種:依賴查找,依賴注入。依賴注入是一種更可取的方式。
??回到Java中,IoC意味著將開發者編寫的Java對象交給IoC容器控制,要理解IoC,就要抓住關鍵詞"Control"。
作為開發者我們控制什么?
- 傳統設計,我們需要訪問對象的成員或使用對象中的方法時,我們需要在程序中通過new進行創建對象,是程序主動的去創建依賴對象。
IoC控制了什么?
- IoC是有專門一個容器來創建這些對象,即由Ioc容器來控制對象的創建;是IoC 容器控制了對象即被動創建了對象;控制什么?那就是主要控制了外部資源獲取(不只是對象包括比如文件等)。
??反轉就好理解了,傳統應用程序是由我們自己在對象中主動控制去直接獲取依賴對象,就是正轉;而反轉則是由容器來幫忙創建及注入依賴對象。對象的控制權反轉了。這就是一種控制反轉的理念,它最大的好處在于降低對象之間的耦合。
IoC實際上是軟件設計中依賴倒置原則的體現,有興趣可以參考這篇文章。
3.面向切片編程AOP
??AOP其實就是一種解耦的思想,并不神秘,其目的就是將項目業務邏輯代碼與一些業務無關瑣碎的事務代碼分離開來。讓開發者只關心業務邏輯部分,不用關系類似于數據庫事務管理、日志管理等瑣碎的事務。
??SpringAOP建立在Java的反射基礎之上,將分布在程序中的公共部分提取出來,做成了切面類(比如數據庫事務)這樣做的好處在于代碼的可重用。一旦涉及到該功能的需求發生變化,只要修改該代碼就行。
從生活中可以很容易舉出例子,比如一個開發者A想把大象塞進冰箱,那么他就要:
- 打開冰箱
- 塞進大象
- 關掉冰箱
??如果此時有開發者B想塞阿貓,開發者C想塞阿狗,那么他們都需要做的公共部分就是打開冰箱和關掉冰箱。那么現在要求,每次打開冰箱的時候都需要在日志上寫上打開冰箱時間,這個時候就發現每個開發者都要加一個寫上時間的步驟。在企業開發中,如果有成百上千個開發者,那么維護成本就會很高。
SpringAOP是怎么做的呢?
??Spring把打開冰箱和關掉冰箱這兩個動作提取出來做成一個切面類,找到切點(切點就是塞這個動作),然后織入(織入就是生成代理對象的過程)。下次開發者A去想要塞大象的時,Spring就會把冰箱打開好,開發者A塞進大象,Spring再來把冰箱關閉。開發者A現在只需要關注自己要干什么,而不必關心打開冰箱和關掉冰箱了。如果要求在每個開發者打開冰箱前在日志上寫下打開時間,那么也只需要改一下切面類中的代碼。
??打開冰箱和關掉冰箱就相當于企業項目中的數據庫事務,而塞大象就相當于業務邏輯代碼。
AOP的實現
??AOP有多種實現,最常使用的就是Spring AOP和AspectJ,Spring只是使用了與AspectJ5一樣的注解,但仍然沒有使用AspectJ的編譯器,底層是動態代理技術的實現,并不依賴于AspectJ的編譯器。
??織入就是一個生成代理對象的過程,一般分為動態織入和靜態織入,動態織入的方式是在運行時動態將要增強的代碼織入到目標類中,這樣往往是通過動態代理技術完成的,靜態織入是指在編譯時期就織入,即:編譯出來的class文件,字節碼就已經被織入了。
SpringAOP是采用動態織入
有兩種實現方式
- 基于接口的動態代理(Dynamic Proxy)
基于繼承的CGLIB代理
動態織入
AspectJ是采用靜態織入
??使用AspectJ的acj編譯器(類似javac)把aspect類編譯成class字節碼后,在java目標類編譯時織入,即先編譯aspect類再編譯目標類。
靜態織入