AOP 全名Aspect-oriented programming 中文翻譯為面向切面编稱.
首先理解代理:
來看一個簡單的例子
package
com.yongping.aoptest;
import java.util.logging.Level;
import java.util.logging.Logger;
public class HelloWorld ... {
private Logger log=Logger.getLogger(this.getClass().getName());
public void hello(String name)...{
//記錄方法執行開始
log.log(Level.INFO, "hello method begin..");
//程序核心邏輯
System.out.println("Hello"+name);
//記錄方法執行結束
log.log(Level.INFO, "hello method end...");
}
}
import java.util.logging.Level;
import java.util.logging.Logger;
public class HelloWorld ... {
private Logger log=Logger.getLogger(this.getClass().getName());
public void hello(String name)...{
//記錄方法執行開始
log.log(Level.INFO, "hello method begin..");
//程序核心邏輯
System.out.println("Hello"+name);
//記錄方法執行結束
log.log(Level.INFO, "hello method end...");
}
}
當執行
hello()
方法時
,
希望在核心邏輯過程執行前後加上記錄動作
,
最簡單的方法就是如上
.
對於
HelloWorld
來說
,
紀錄執行前後的動作並不是
HelloWorld
的業務邏輯
,
這樣就增加了代碼的冗餘
,
如果客戶要求更改紀錄執行時的輸出語句
,
那就得大動干戈
,
逐個類進行修改
.
可以使用代理來解決這個問題
,
常用的有兩種代理方式
靜態代理
(Static proxy)
與動態代理
(Dynamic proxy).
靜態代理
:
代理對象與被代理對象都必須實現同ㄧ個接口
,
在代理對象中可以實現日志紀錄等操作
,
並在需要的時候掉用被代理對象
,
這樣的話被代理對象就只保留業務過程
.
(
其實不用實現同一個接口也可以實現代理
,
但是在程序被調用的時候
,
掉用的是接口的引用
,
調用程序首先處理的是代理對象
,
由代理對象調用被代理的對象
,
展現給用戶的是在被代理對象的業務邏輯中添加了代碼
.)
在使用的時候順序是
先定義一個接口的引用
,
再創建一個代理的對象給接口引用
,
創見代理對象時注入邏輯實現的對象
.
這個過程很巧妙
.
調用者來說
,
我只調用接口類型
,
接口給了他一個代理
,
代理裡面封裝了邏輯對象
,
封裝外圍加入了非邏輯的
log.
詳細過程如下
:
接口
:
package
com.yongping.aoptest;
public interface IHello ... {
public void hello(String name);
}
public interface IHello ... {
public void hello(String name);
}
核心邏輯實現類
:
package
com.yongping.aoptest.impl;
import com.yongping.aoptest.IHello;
public class StrHelloImpl implements IHello ... {
public void hello(String name) ...{
System.out.println("Hello,"+name);
}
}
import com.yongping.aoptest.IHello;
public class StrHelloImpl implements IHello ... {
public void hello(String name) ...{
System.out.println("Hello,"+name);
}
}
代理實現類
:
package
com.yongping.aoptest.impl;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.yongping.aoptest.IHello;
public class ProxyHello implements IHello ... {
private Logger log = Logger.getLogger(this.getClass().getName());
public IHello helloObject;
public ProxyHello(IHello helloObject)...{
this.helloObject=helloObject;
}
public void hello(String name) ...{
log.log(Level.INFO, "method star.........");
helloObject.hello(name);
log.log(Level.INFO, "method end..............");
}
}
import java.util.logging.Level;
import java.util.logging.Logger;
import com.yongping.aoptest.IHello;
public class ProxyHello implements IHello ... {
private Logger log = Logger.getLogger(this.getClass().getName());
public IHello helloObject;
public ProxyHello(IHello helloObject)...{
this.helloObject=helloObject;
}
public void hello(String name) ...{
log.log(Level.INFO, "method star.........");
helloObject.hello(name);
log.log(Level.INFO, "method end..............");
}
}
測試過程
(
使用
junit4.0)
package
com.yongping.aoptest;
import org.junit.Test;
import com.yongping.aoptest.impl.ProxyHello;
import com.yongping.aoptest.impl.StrHelloImpl;
public class TestHello ... {
@Test
public void testHello()...{
IHello helloworld;
helloworld=new ProxyHello(new StrHelloImpl());
helloworld.hello("guoguo");
}
}
import org.junit.Test;
import com.yongping.aoptest.impl.ProxyHello;
import com.yongping.aoptest.impl.StrHelloImpl;
public class TestHello ... {
@Test
public void testHello()...{
IHello helloworld;
helloworld=new ProxyHello(new StrHelloImpl());
helloworld.hello("guoguo");
}
}