W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎勵
“面向切面編程”也被稱為“Aop”,是目前非常活躍的一個開發(fā)思想。利用 AOP 可以對業(yè)務(wù)邏輯的各個部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的 可重用性,同時提高了開發(fā)的效率。
Aop 編程的目的是將例如日志記錄、性能統(tǒng)計(jì)、安全控制、事務(wù)、異常處理等代碼從業(yè) 務(wù)邏輯代碼中劃分出來。
比方說我有一個查詢用戶信息的接口,現(xiàn)在要為這個接口添加記錄的功能。每當(dāng)執(zhí)行一 次查詢都記錄下查詢消耗時間。如果我要實(shí)現(xiàn)這個功能,一般情況下需要在接口實(shí)現(xiàn)類的每 一個方法前后都要安插代碼來收集數(shù)據(jù)。如果這樣做的話會比較繁瑣,但是通過 Aop 的方式 就顯得非常優(yōu)雅。
實(shí)現(xiàn) Aop 編程模型分為(靜態(tài)代理、動態(tài)代理)兩種方式,其中靜態(tài)代理多以代理模式 (Proxy Pattern)的形式出現(xiàn)。而動態(tài)代理則花樣繁多,常見的有:Java 原生的 Propxy、 CGLib、JBossAOP、等。
假設(shè)有一個工廠,工廠里的工人上下班每次都需要打卡。那么這個工廠的工人可以抽象為 Worker 接口、工作可以被抽象成為 doWork 方法。一個對象化的工人就構(gòu)建出來了如下:
public interface Worker {
public void doWork();
}
打卡分為上班打卡和下班打卡,為此抽象一個打卡機(jī),并將上下班打卡使用 beforeWork 和 afterWork 方法表示。如下:
public class Machine {
public void beforeWork() {
...
}
public void afterWork() {
...
}
}
工廠規(guī)定每個員工只要來到工廠就視為上班打卡、當(dāng)離開工廠就被認(rèn)為下班打卡。為了 人性化考勤,公司使用了一種現(xiàn)代化的技術(shù)可以讓員工不必自己動手去打卡,猶如配備了一 名貼身小秘書。
其實(shí)不難看出這項(xiàng)新技術(shù)僅僅是圍繞著工人(Worker)在工作(doWork)前后實(shí)現(xiàn)了自動打卡。下面是這個技術(shù)的抽象:
public class WorkerProxy implements Worker {
private Machine machine;
private Worker targetWorker;
public void doWork() {
this.machine.beforeWork();
this.targetWorker.doWork();
this.machine.afterWork();
}
}
在靜態(tài)代理中所有類型都是衡定的。在程序執(zhí)行時,代理類(WorkerProxy)的 class文件已經(jīng)預(yù)先存在。在動態(tài)代理中這卻恰恰相反的,代理類不會預(yù)先存在,當(dāng)需要它的時候通過一些專門的類庫創(chuàng)建這個代理程序。
比方說一個程序中有多種不同的 Servies 類。我們要打印出調(diào)用每個業(yè)務(wù)方法所占用的 時間。如果使用靜態(tài)代理方式會發(fā)現(xiàn),程序中根本不存在衡定的“doWorker”方法。
雖然不存在衡定的“doWorker”方法,但是調(diào)用行為是存在的。而且可以將其行為抽象 出來這就是 Aop 中的“切面”,負(fù)責(zé)執(zhí)行這個切面的類就叫“攔截器”。下面這個代碼展示 了如何用 Java 的原生支持實(shí)現(xiàn)動態(tài)代理。
ClassLoader lod = Thread.currentThread().getContextClassLoader();
Class<?>[] faceSet = new Class[] { TestBean2_Face.class };
Object proxy = Proxy.newProxyInstance(
lod, faceSet, new JavaInvocationHandler()
);
TestBean2_Face face = (TestBean2_Face) proxy;
System.out.println(face.toString());
下面的攔截器就是上面例子中用到的:“JavaInvocationHandler”類。
class JavaInvocationHandler implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) {
return null; // TODO Auto-generated method stub
}
}
由此可見在 Java 中實(shí)現(xiàn)一個動態(tài)代理還算很簡單的,但是有的時候我們想把所有 Bean 都管理起來。并且按照自己的意愿來對其進(jìn)行動態(tài)代理,在這種要求下我們不得不自己去開發(fā)一套 Bean 管理程序,或者使用更為成熟的框架例如:Spring、Guice、或者您也可以使用 Hasor 進(jìn)行 Bean 的管理。
Hasor 的 Aop 聲明使用方式和 JDK 自帶的很相似,但是由于 Hasor 具有 Bean 管理的功能,因此 Hasor 很容易在一批 Bean 上使用動態(tài)代理功能。這將會大大減少重復(fù)代碼的開發(fā),而且 Hasor 還可以通過匹配器讓您自己框選符合條件的 Bean,不同于 Spring 的是 Hasor 提供的 Api 更加注重編程性而非配置聲明。
public class SimpleInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
try {
System.out.println("before...");
Object returnData = invocation.proceed();
System.out.println("after...");
return returnData;
} catch (Exception e) {
throw e;
}
}
}
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: