1. 程式人生 > >Spring IOC與AOP

Spring IOC與AOP

      使用spring這麼久了,從來沒好好的總結一下這兩個核心的技術,關於這兩個技術的資料數不勝數,自己也看過一些書、查過一些資料,不過可能由於個人水平有限,總是弄的混混惡惡的,因此今天抽空總結一下。

1、IOC

       先從IOC說起,我們平常使用物件的時候,一般都是直接使用關鍵字類new一個物件,使用new那麼就表示當前模組已經不知不覺的和new的物件耦合了。而我們通常都是更高層次的抽象模組呼叫底層的實現模組,這樣也就產生了模組依賴於具體的實現,這樣與我們JAVA中提倡的面向介面面向抽象程式設計是相沖突的。例如:我們在進行資料庫操作的時候,總是業務層呼叫DAO層,當然我們的DAO一般都是會採用介面開發,這在一定程度上滿足了鬆耦合,使業務邏輯層不依賴於具體的資料庫DAO層。(但是我們在使用的時候還是會new一個特定資料庫的DAO層,這無形中也與特定的資料庫綁定了)

      IOC,就是DAO介面的實現不再是業務邏輯層呼叫工廠類去獲取,而是通過容器(比如spring)來自動的為我們的業務層設定DAO的實現類。這樣整個過程就反過來,以前是我們業務層主動去獲取DAO,而現在是DAO主動被設定到業務邏輯層中來了,這也就是反轉控制的由來。

2、AOP

       舉個例子:當一個類中有5個方法,呼叫每個方法之前都要檢查使用者是否具有許可權,我們可以定義一個公共方法A,5個方法中每個方法都呼叫該公共方法A。如果類中有100個方法,每次呼叫固然很麻煩,如果哪天需求變了,不需要呢,一個個去掉嗎,更費勁。

      AOP 的底層實際上是由動態代理實現的。AOP 代理其實是由 AOP 框架動態生成的一個代理物件,該物件可作為目標物件使用。AOP 代理物件包含了目標物件的全部方法,同時又添加了特殊的處理方法,如上面說的檢查許可權之類的操作。所以,是在原目標物件上添加了特殊功能。

最最經典的例項===

定義一個介面:

public interface IHello { 
       void sayHello(String name); 
} 

 寫個類實現IHello介面

public class Hello implements IHello { 

    public void sayHello(String name) { 
        System.out.println("Hello " + name); 
    } 

} 

 現在我們要為這個業務方法加上日誌記錄的業務,我們在不改變原始碼的情況下,我們會去怎麼做呢?也許,你會去寫一個類去實現IHello介面,並依賴Hello這個類.程式碼如下: 

public class HelloProxy implements IHello { 
    private IHello hello; 
 
    public HelloProxy(IHello hello) { 
        this.hello = hello; 
    } 

   public void sayHello(String name) { 
        Logger.logging(Level.DEBUGE, "sayHello method start."); 
        hello.sayHello(name); 
        Logger.logging(Level.INFO, "sayHello method end!"); 
 
   } 
 
} 

.Logger類和Level列舉程式碼如下:

Logger.java 
 
import java.util.Date; 

public class Logger{ 
     
    public static void logging(Level level, String context) { 
        if (level.equals(Level.INFO)) { 
            System.out.println(new Date().toLocaleString() + " " + context); 
       } 
        if (level.equals(Level.DEBUGE)) { 
           System.err.println(new Date() + " " + context); 
       } 
   } 

} 

Level.java 
 
public enum Level { 
    INFO,DEBUGE; 
} 

測試:

public class Test { 
    public static void main(String[] args) { 
        IHello hello = new HelloProxy(new Hello()); 
        hello.sayHello("Doublej"); 
    } 
} 

hello物件是被HelloProxy這個所謂的代理態所建立的.這樣,如果我們以後要把日誌記錄的功能去掉.那我們只要把得到hello物件的程式碼改成以下: 

public class Test { 
    public static void main(String[] args) { 
        IHello hello = new Hello(); 
        hello.sayHello("Doublej"); 
    } 
}