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