1. 程式人生 > >SSH中各個框架的作用以及Spring AOP,IOC,DI詳解

SSH中各個框架的作用以及Spring AOP,IOC,DI詳解

在SSH框假中spring充當了管理容器的角色。我們都知道Hibernate用來做持久層,因為它將JDBC做了一個良好的封裝,程式設計師在與資料庫進行互動時可以不用書寫大量的SQL語句。Struts是用來做應用層的,他它負責呼叫業務邏輯serivce層。所以SSH框架的流程大致
是:Jsp頁面----Struts------Service(業務邏輯處理類)---Hibernate(左到右)struts負責控制Service(業務邏輯處理類),從而控制了Service的生命週期,這樣層與層之間的依賴和強,屬於耦合。這時,使用spring框架就起到了控制Action物件(Strus中的)和Service類的作用,兩者之間的關係就鬆散了,Spring的Ioc機制(控制反轉和依賴注入)正是用在此處

首先想說說IoC(Inversion of Control,控制倒轉)。這是spring的核心,貫穿始終。所謂IoC,對於spring框架來說,就是由spring來負責控制物件的生命週期和物件間的關係。這是什麼意思呢,舉個簡單的例子,我們是如何找女朋友的?常見的情況是,我們到處去看哪裡有長得漂亮身材又好的mm,然後打聽她們的興趣愛好、qq號、電話號、ip號、iq號………,想辦法認識她們,投其所好送其所要,然後嘿嘿……這個過程是複雜深奧的,我們必須自己設計和麵對每個環節。傳統的程式開發也是如此,在一個物件中,如果要使用另外的物件,就必須得到它(自己new一個,或者從JNDI中查詢一個),使用完之後還要將物件銷燬(比如Connection等),物件始終會和其他的介面或類藕合起來。

那麼IoC是如何做的呢?有點像通過婚介找女朋友,在我和女朋友之間引入了一個第三者:婚姻介紹所。婚介管理了很多男男女女的資料,我可以向婚介提出一個列表,告訴它我想找個什麼樣的女朋友,比如長得像李嘉欣,身材像林熙雷,唱歌像周杰倫,速度像卡洛斯,技術像齊達內之類的,然後婚介就會按照我們的要求,提供一個mm,我們只需要去和她談戀愛、結婚就行了。簡單明瞭,如果婚介給我們的人選不符合要求,我們就會丟擲異常。整個過程不再由我自己控制,而是有婚介這樣一個類似容器的機構來控制。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代理

代理類的代理方法生成的過程

織入

通知根據攔截目標類中的目標方法的位置不一樣可以分為:前置通知、後置通知、最終通知、環繞通知、異常通知

2AOP實現的兩種模式

        (1)、xml形式

 (2)、註解形式

AOP原理:

概念:代理模式的英文叫做ProxySurrogate,中文都可譯為”代理“,所謂代理,就是一個人或者一個機構代表另一個人或者另一個機構採取行動。在一些情況下,一個客戶不想或者不能夠直接引用一個物件,而代理物件可以在客戶端和目標物件之間起到中介的作用

    1、JDK動態代理

JDK的動態代理必須具備四個條件:

          目標介面

          目標類

          攔截器

          代理類

總結:

    1、因為利用JDKProxy生成的代理類實現了介面,所以目標類中所有的方法在代理類中都有。

    2、生成的代理類的所有的方法都攔截了目標類的所有的方法。而攔截器中invoke方法的內容正好就是代理類的各個方法的組成體。

    3、利用JDKProxy方式必須有介面的存在。

    4、invoke方法中的三個引數可以訪問目標類的被呼叫方法的API、被呼叫方法的引數、被呼叫方法的返回型別。

2、CGLIB做代理

    1、 CGlib是一個強大的,高效能,高質量的Code生成類庫。它可以在執行期擴充套件Java類與實現Java介面。

    2、 用CGlib生成代理類是目標類的子類。

    3、 用CGlib生成 代理類不需要介面

    4、 用CGLib生成的代理類重寫了父類的各個方法。

    5、 攔截器中的intercept方法內容正好就是代理類中的方法體

spring有兩種代理方式:

1. 若目標物件實現了若干介面,spring使用JDKjava.lang.reflect.Proxy類代理。

    優點:因為有介面,所以使系統更加鬆耦合

    缺點:為每一個目標類建立介面

2. 若目標物件沒有實現任何介面,spring使用CGLIB庫生成目標物件的子類。

    優點:因為代理類與目標類是繼承關係,所以不需要有介面的存在。

    缺點:因為沒有使用介面,所以系統的耦合性沒有使用JDK的動態代理好。

Spring的動態代理實現:

    1、 攔截器必須實現MethodInterceptor介面

    2、 spring中的配置

    總結:不管採用JDK動態代理生成代理類還是採用CGLIB生成動態代理類。目標類中的所有方法都被攔截下來。而在哪個方法裡做比如許可權的判斷、安全性的檢查等一系列工做必須在攔截器中作相應的判斷。但是這樣的程式設計形式給程式的編寫帶來了一定的麻煩。

1、 在攔截器中控制哪些方法將被做許可權判斷、安全性檢查等是一件比較困難的事情。

    A. 採取這樣的配置目標類只能是一個,所以如果用這種方法做許可權控制,得寫很多代理,這樣給程式碼的書寫造成了困難。

    B. 每一個類中的每一個方法如果都有不同的許可權(實際的系統往往都是這樣的),在攔截器中的判斷程式碼書寫會很困難。

2、 這樣的程式碼也會導致硬編碼,也就是說我們必須在攔截器中寫一些許可權判斷等事情,會導致攔截器中程式碼量的增大,造成維護的麻煩。