在SSH框假中spring充當了管理容器的角色。咱們都知道Hibernate用來作持久層,由於它將JDBC作了一個良好的封裝,程序員在與數據庫進行交互時能夠不用書寫大量的SQL語句。Struts是用來作應用層的,他它負責調用業務邏輯serivce層。因此SSH框架的流程大體
是:Jsp頁面----Struts------Service(業務邏輯處理類)---Hibernate(左到右)struts負責控制Service(業務邏輯處理類),從而控制了Service的生命週期,這樣層與層之間的依賴和強,屬於耦合。這時,使用spring框架就起到了控制Action對象(Strus中的)和Service類的做用,二者之間的關係就鬆散了,Spring的Ioc機制(控制反轉和依賴注入)正是用在此處java
首先想說說IoC(Inversion of Control,控制倒轉)。這是spring的核心,貫穿始終。所謂IoC,對於spring框架來講,就是由spring來負責控制對象的生命週期和對象間的關係。這是什麼意思呢,舉個簡單的例子,咱們是如何找女友的?常見的狀況是,咱們處處去看哪裏有長得漂亮身材又好的mm,而後打聽她們的興趣愛好、qq號、電話號、ip號、iq號………,想辦法認識她們,投其所好送其所要,而後嘿嘿……這個過程是複雜深奧的,咱們必須本身設計和麪對每一個環節。傳統的程序開發也是如此,在一個對象中,若是要使用另外的對象,就必須獲得它(本身new一個,或者從JNDI中查詢一個),使用完以後還要將對象銷燬(好比Connection等),對象始終會和其餘的接口或類藕合起來。程序員
那麼IoC是如何作的呢?有點像經過婚介找女友,在我和女友之間引入了一個第三者:婚姻介紹所。婚介管理了不少男男女女的資料,我能夠向婚介提出一個列表,告訴它我想找個什麼樣的女友,好比長得像李嘉欣,身材像林熙雷,唱歌像周杰倫,速度像卡洛斯,技術像齊達內之類的,而後婚介就會按照咱們的要求,提供一個mm,咱們只須要去和她談戀愛、結婚就好了。簡單明瞭,若是婚介給咱們的人選不符合要求,咱們就會拋出異常。整個過程再也不由我本身控制,而是有婚介這樣一個相似容器的機構來控制。Spring所倡導的開發方式就是如此,全部的類都會在spring容器中登記,告訴spring你是個什麼東西,你須要什麼東西,而後spring會在系統運行到適當的時候,把你要的東西主動給你,同時也把你交給其餘須要你的東西。全部的類的建立、銷燬都由 spring來控制,也就是說控制對象生存週期的再也不是引用它的對象,而是spring。對於某個具體的對象而言,之前是它控制其餘對象,如今是全部對象都被spring控制,因此這叫控制反轉。spring
IoC的一個重點是在系統運行中,動態的向某個對象提供它所須要的其餘對象。這一點是經過DI(Dependency Injection,依賴注入)來實現的。好比對象A須要操做數據庫,之前咱們老是要在A中本身編寫代碼來得到一個Connection對象,有了 spring咱們就只須要告訴spring,A中須要一個Connection,至於這個Connection怎麼構造,什麼時候構造,A不須要知道。在系統運行時,spring會在適當的時候製造一個Connection,而後像打針同樣,注射到A當中,這樣就完成了對各個對象之間關係的控制。A須要依賴 Connection才能正常運行,而這個Connection是由spring注入到A中的,依賴注入的名字就這麼來的。那麼DI是如何實現的呢? Java 1.3以後一個重要特徵是反射(reflection),它容許程序在運行的時候動態的生成對象、執行對象的方法、改變對象的屬性,spring就是經過反射來實現注入的。數據庫
AOP編程編程
這個概念有點複雜!首先仍是打個比方吧!好比咱們在要在網站上註冊登陸的案例,在註冊時咱們要完成校驗,文件上傳,獲取用戶信息只有將這些動做完成後才能作保存用戶的操做,若是報全部的業務邏輯放到一塊兒處理的話,那麼就顯得過於繁雜不利於後期的開發和維護,AOP的作法是把目標類(又稱目標對象)保存用戶單獨提出來,把校驗,文件上傳,獲取用戶信息當作切面,這樣就很好的作到了解耦把業務邏輯和切面分離,有利於開發和後期維護!安全
概念:框架
A. Aspect(切面)好比說事務、權限等,與業務邏輯沒有關係的部分 性能
B. joinpoint(鏈接點)目標類的目標方法。(由客戶端在調用的時候決定)網站
C. Pointcut(切入點)所謂切入點是指咱們要對那些攔截的方法的定義.被歸入spring aop中的目標類的方法。編碼
D. Advice(通知)所謂通知是指攔截到joinpoint以後所要作的事情就是通知.通知分爲前置通知,後置通知,異常通知,最終通知,環繞通知(切面要完成的功能)
E. Target(目標對象):代理的目標對象
F. Weaving(織入)是指把切面應用到目標對象來建立新的代理對象的過程.切面在指定的鏈接點織入到目標對象
JDKProxy代理 |
SpringAop |
目標對象 |
目標對象 |
攔截器類 |
切面 |
攔截器類中的方法 |
通知 |
被攔截到的目標類中方法的集合 |
切入點 |
在客戶端調用的方法(目標類目標方法) |
鏈接點 |
代理類 |
AOP代理 |
代理類的代理方法生成的過程 |
織入 |
通知根據攔截目標類中的目標方法的位置不同能夠分爲:前置通知、後置通知、最終通知、環繞通知、異常通知
二、AOP實現的兩種模式
(1)、xml形式
(2)、註解形式
AOP原理:
概念:代理模式的英文叫作Proxy或Surrogate,中文均可譯爲」代理「,所謂代理,就是一我的或者一個機構表明另外一我的或者另外一個機構採起行動。在一些狀況下,一個客戶不想或者不可以直接引用一個對象,而代理對象能夠在客戶端和目標對象之間起到中介的做用
一、JDK動態代理
JDK的動態代理必須具有四個條件:
目標接口
目標類
攔截器
代理類
總結:
一、由於利用JDKProxy生成的代理類實現了接口,因此目標類中全部的方法在代理類中都有。
二、生成的代理類的全部的方法都攔截了目標類的全部的方法。而攔截器中invoke方法的內容正好就是代理類的各個方法的組成體。
三、利用JDKProxy方式必須有接口的存在。
四、invoke方法中的三個參數能夠訪問目標類的被調用方法的API、被調用方法的參數、被調用方法的返回類型。
二、CGLIB作代理
一、 CGlib是一個強大的,高性能,高質量的Code生成類庫。它能夠在運行期擴展Java類與實現Java接口。
二、 用CGlib生成代理類是目標類的子類。
三、 用CGlib生成 代理類不須要接口
四、 用CGLib生成的代理類重寫了父類的各個方法。
五、 攔截器中的intercept方法內容正好就是代理類中的方法體
spring有兩種代理方式:
1. 若目標對象實現了若干接口,spring使用JDK的java.lang.reflect.Proxy類代理。
優勢:由於有接口,因此使系統更加鬆耦合
缺點:爲每個目標類建立接口
2. 若目標對象沒有實現任何接口,spring使用CGLIB庫生成目標對象的子類。
優勢:由於代理類與目標類是繼承關係,因此不須要有接口的存在。
缺點:由於沒有使用接口,因此係統的耦合性沒有使用JDK的動態代理好。
Spring的動態代理實現:
一、 攔截器必須實現MethodInterceptor接口
二、 在spring中的配置
總結:無論採用JDK動態代理生成代理類仍是採用CGLIB生成動態代理類。目標類中的全部方法都被攔截下來。而在哪一個方法裏作好比權限的判斷、安全性的檢查等一系列工作必須在攔截器中做相應的判斷。可是這樣的編程形式給程序的編寫帶來了必定的麻煩。
一、 在攔截器中控制哪些方法將被作權限判斷、安全性檢查等是一件比較困難的事情。
A. 採起這樣的配置目標類只能是一個,因此若是用這種方法作權限控制,得寫不少代理,這樣給代碼的書寫形成了困難。
B. 每個類中的每個方法若是都有不一樣的權限(實際的系統每每都是這樣的),在攔截器中的判斷代碼書寫會很困難。
二、 這樣的代碼也會致使硬編碼,也就是說咱們必須在攔截器中寫一些權限判斷等事情,會致使攔截器中代碼量的增大,形成維護的麻煩。