Java實現(xiàn)AOP面向切面編程的實例教程_第1頁
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、Java實現(xiàn)AOP面向切面編程的實例教程這篇文章主要介紹了Java實現(xiàn)AOP面向切面編程的實例教程,通常Java中的AOP都是利用Spring框架中造好的輪子來開發(fā),而本文則關(guān)注于Java本身AOP的設(shè)計模式實現(xiàn),需要的朋友可以參考下介紹 眾所周知,AOP(面向切面編程)是Spring框架的特色功能之一。通過設(shè)置橫切關(guān)注點(cross cutting concerns),AOP提供了極高的擴(kuò)展性。那AOP在Spring中是怎樣運作的呢?當(dāng)你只能使用core java,卻需要AOP技術(shù)時,這個問題的解答變得極為關(guān)鍵。不僅如此,在高級技術(shù)崗位的面試中,此類問題也常作為考題出現(xiàn)。這不,我的朋友最近參

2、加了一個面試,就被問到了這樣一個棘手的問題如何在不使用Spring及相關(guān)庫,只用core Java的條件下實現(xiàn)AOP。因此,我將在本文中提供一份大綱,幫助大家了解如何只用core Java實現(xiàn)一個AOP(當(dāng)然啦,這種AOP在功能上有一定的局限性)。注意,本文不是一篇有關(guān)Spring AOP與Java AOP的對比研究,而是有關(guān)在core Java中借助固有的設(shè)計模式實現(xiàn)AOP的教程。 想必讀者已經(jīng)知道AOP是什么,也知道在Spring框架中如何使用它,因此本文只著眼于如何在不用Spring的前提下實現(xiàn)AOP。首先,我們得知道,Spring是借助了JDK proxy和CGlib兩種技術(shù)實現(xiàn)AOP

3、的。JDK dynamic proxy提供了一種靈活的方式來hook一個方法并執(zhí)行指定的操作,但執(zhí)行操作時得有一個限制條件:必須先提供一個相關(guān)的接口以及該接口的實現(xiàn)類。實踐出真知,讓我們透過一個案例來理解這句吧!現(xiàn)在有一個計算器程序,用于完成一些數(shù)學(xué)運算。讓我們來考慮下除法功能,此時的問題是:如果core framework 已經(jīng)具備了一份實現(xiàn)除法的代碼,我們能否在代碼執(zhí)行時劫持(highjack)它并執(zhí)行額外的校驗?zāi)??答案是肯定的,我將用下面提供的代碼片段來證明這點。首先來看基礎(chǔ)接口的代碼:public interface Calculator public int calculate( i

4、nt a , int b); 該接口實現(xiàn)類的代碼如下:public class CalculatorImpl implements Calculator Override public int calculate(int a, int b) return a/b; 假設(shè)我們既不能修該上面的代碼,也不能對核心庫進(jìn)行任何改動,怎樣才能完美地實現(xiàn)校驗功能呢?不如試下JDK dynamic proxy的功能吧。public class SomeHandler implements InvocationHandler / Code omitted for simplicity. Override pub

5、lic Object invoke(Object proxy, Method method, Object params) throws Throwable / Your complex business validation and logic Object result = method.invoke(targetObject ,params); return result; 讓我們通過測試類來看看由JDK dynamic proxy實現(xiàn)的校驗功能的效果如何。public static void main(String args) CalculatorImpl calcImpl = new

6、 CalculatorImpl(); Calculator proxied = (Calculator)ProxyFactory.getProxy (Calculator.class, calcImpl, new SomeHandler(calcImpl); int result = calculate(20, 10); System.out.println(FInal Result : + result); 從結(jié)果可以看出,簡單地實現(xiàn)功能強(qiáng)大的InvocationHandler接口,我們便能得到一個hooking implementation。按照J(rèn)DK文檔的描述,InvocationHan

7、dler接口是借助一個代理實例(proxy instance)來處理一個方法調(diào)用的。 現(xiàn)在我們已經(jīng)知道,InvocationHandler的invoke()方法能夠幫助我們解決問題。那么再來解決一個新問題怎樣才能在方法執(zhí)行的前后執(zhí)行操作呢?說的更具體一些,我們能通過添加多個aop(before、after、around)來hook一個方法嗎(譯注:原文為add multiple aops,但我認(rèn)為Handler是充當(dāng)Aspect的角色)?答案同樣是肯定的。按照以下的步驟建立一個精簡的代碼模板便能滿足這樣的需求: 1.創(chuàng)建一個抽象類,用于將aop應(yīng)用于目標(biāo)對象上。2.創(chuàng)建名為BeforeHand

8、ler 和 AfterHandler的兩個aop。前者在方法執(zhí)行之前工作,而后者則在方法執(zhí)行結(jié)束后工作。3.創(chuàng)建一個代理類,使所有的aop handler和目標(biāo)對象只需作為參數(shù)傳入,就能創(chuàng)建一個hook。4.加入你自己的業(yè)務(wù)邏輯或者橫切關(guān)注點。5.最后,通過傳入相關(guān)的參數(shù)創(chuàng)建代理對象(proxy object)。 兩種實現(xiàn)AOP的方式: 1,JDK提供的動態(tài)代理實現(xiàn) 接口 public interface UserBean void getUser(); void addUser(); void updateUser(); void deleteUser(); 原始實現(xiàn)類 public cla

9、ss UserBeanImpl implements UserBean private String user = null; public UserBeanImpl() public UserBeanImpl(String user) this.user = user; public String getUserName() return user; public void getUser() System.out.println(this is getUser() method!); public void setUser(String user) this.user = user; Sy

10、stem.out.println(this is setUser() method!); public void addUser() System.out.println(this is addUser() method!); public void updateUser() System.out.println(this is updateUser() method!); public void deleteUser() System.out.println(this is deleteUser() method!); 代理類 import java.lang.reflect.Invocat

11、ionHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import com.cignacmc.finance.bean.UserBeanImpl; public class UserBeanProxy implements InvocationHandler private Object targetObject; public UserBeanProxy(Object targetObject) his.targetObject = targetObject; public Object in

12、voke(Object proxy, Method method, Object args) throws Throwable UserBeanImpl userBean = (UserBeanImpl) targetObject; String userName = userBean.getUserName(); Object result = null; /權(quán)限判斷 if(userName != null & !.equals(userName) result = method.invoke(targetObject, args); return result; 測試類 import ja

13、va.lang.reflect.Proxy; import com.cignacmc.finance.bean.UserBean; import com.cignacmc.finance.bean.UserBeanImpl; import xy.UserBeanProxy; public class ProxyExe public static void main(String args) System.out.println(Proved.); UserBeanImpl targetObject = new UserBeanImpl(Bob Liang); UserBeanProxy pro

14、xy = new UserBeanProxy(targetObject); /生成代理對象 UserBean object = (UserBean)Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), proxy); object.addUser(); System.out.println(NO Proved.); targetObject = new UserBeanImpl(); proxy = new UserBeanProxy(t

15、argetObject); /生成代理對象 object = (UserBean)Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), proxy); object.addUser(); 輸出: Proved. this is addUser() method! NO Proved. 從上面這個例子可以成功攔截了調(diào)用的方法addUser()并對其做了相應(yīng)的處理 2, 通過cglib創(chuàng)建代理類 好處是不要求我們的目標(biāo)對象實現(xiàn)接口 原始類 p

16、ublic class ClientBean private String name = null; public ClientBean() public ClientBean(String name) = name; public void addClient() System.out.println(this is addClient() method!); public void deleteClient() System.out.println(this is deleteClient() method!); public void getClient() System.out.pri

17、ntln(this is getClient() method!); public void updateClient() System.out.println(this is updateClient() method!); public String getClientName() return name; public void setClientName(String name) = name; 代理類 import java.lang.reflect.Method; import com.cignacmc.finance.bean.ClientBean; import xy.Enha

18、ncer; import xy.MethodInterceptor; import xy.MethodProxy; public class CGLibProxy implements MethodInterceptor private Object targetObject; public Object createProxyObject(Object targetObject) this.targetObject = targetObject; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.targetObj

19、ect.getClass(); enhancer.setCallback(this); return enhancer.create(); public Object intercept(Object proxy, Method method, Object args, MethodProxy methodProxy) throws Throwable ClientBean clientBean = (ClientBean)targetObject; String userName = clientBean.getClientName(); Object result = null; if(userName != null & !.equals(userName) result = method.invoke(targetObject, args); return result; 測試類 import java.lang.reflect.Proxy; import com.cignacmc.

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論