(Why)為什么會有AOP:
(目前理解)業(yè)務代碼被重復性的非核心的代碼所混淆音念,并且占據(jù)了大量的空間站刑,造成混亂。比如:log宪睹,數(shù)據(jù)庫的連接與關閉,數(shù)據(jù)庫事務的控制以及控制方法的訪問權限等等蚕钦。
public void test(String param) {
LogUtils.info("==> [test] starts, the param: " + param);
// do something
// ....
LogUtils.info("<== [test] end);
}
可以看到log是非核心代碼亭病,但是在各個方法中都會有出現(xiàn)。所以希望能夠?qū)I(yè)務代碼與非核心代碼隔離開來嘶居。
(How)怎么解決呢:
觀察這些非核心代碼罪帖,應該有會發(fā)現(xiàn)他們基本上出現(xiàn)在方法的前面和后面位置,那么能不能轉(zhuǎn)化成另一種形式:
public void test(String param) {
LogUtils.info("==> [test] starts, the param: " + param);
test(param); //此處調(diào)用目標方法邮屁,當然該方法中不必有l(wèi)og代碼了
LogUtils.info("<== [test] end);
}
我們希望有一項技術能夠幫我們 自動的 給特定方法 都生成 相應的帶有增強性功能的方法整袁。即 動態(tài)代理。
/**
* Created by xiaoyiyiyo on 2018/5/23.
*/
public class ProxyFactory implements InvocationHandler{
//目標類
private Object target;
//提供構造函數(shù)佑吝,支持目標類傳入
public ProxyFactory(Object target) {
this.target = target;
}
/**
* 核心方法:用于增強以及回調(diào)目標方法
* @param proxy 代理對象
* @param method 目標方法對象坐昙,可用于回調(diào)
* @param args 目標方法的參數(shù)值
* @return 一般用于返回目標方法的返回值
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// args即為目標方法的參數(shù)值,可以再細致化處理
LogUtils.info("==> [test] starts, the param: " + args.toString());
// 可以在這里利用method反射 過濾判斷增強目標類的哪些特定方法
// 此處調(diào)用目標方法
Object result = method.invoke(target, args);
LogUtils.info("<== [test] end");
return result;
}
// 獲取代理對象
public Object getProxy() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
this);
}
}
這樣得到一個目標類的代理類芋忿,利用這個代理類來代替原來的類進行我們的業(yè)務處理操作炸客。
動態(tài)代理主要有兩種: JDK動態(tài)代理疾棵, CGLib動態(tài)代理 (自行研究它們的原理。)
區(qū)別:
JDK動態(tài)代理痹仙,需要目標類有接口是尔,生成的代理類實現(xiàn)這個接口,這樣可以包含目標類的所有方法蝶溶。
CGLib動態(tài)代理,可以不需要有接口宣渗,利用目標類作為父類抖所,生成的代理類繼承目標類,同樣可以拿到目標類的方法痕囱。
總結(jié)一句話:
AOP: 在內(nèi)存中臨時生成一個AOP代理對象田轧,這個對象包含了目標對象的全部方法,并且在特定的切點(某些方法)做了增強處理(非核心代碼)鞍恢,回調(diào)原對象的方法傻粘。
怎么完善AOP(自己實現(xiàn)簡版AOP)
幾個關鍵概念:
通知(advise): 即想要的功能代碼,如 日志帮掉,事務弦悉,安全等。一般包含before, after方法蟆炊,用來表明增強 目標方法的前面還是后面稽莉。
切入點(Pointcut): 即需要增強 哪些目標類哪些方法
通知器(advisor): advise + pointcut, 這樣一起就表明: 在哪里干什么涩搓,什么時候干污秆。
切面(Aspect): 類似于通知器,代碼寫法不一樣而已昧甘。
實現(xiàn)AOP框架的流程:=良拼。=
。充边。庸推。待續(xù)(有點忙,容我構思下語言和繪圖浇冰,最近幾天出爐)