日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

Java核心庫實現簡單的AOP

瀏覽:27日期:2022-08-26 16:51:31

Spring是一個十分火熱開源框架,而AOP(面向切面編程)則是Spring最重要的概念之一,為了更好的理解和學習AOP的思想,使用核心庫來實現一次不失為一個好方法。

首先介紹一下AOP的概念,AOP(Aspect Oriented Programming),即面向切面編程,所謂的面向切面編程,就是從一個橫切面的角度去設計代碼的思想,傳統的OOP思想是用封裝繼承和多態構造一種縱向的層次關系,但不適合定義橫向的關系,而AOP思想則對此進行了很好的補充。

例如日志管理代碼往往橫向的散布在很多對象層次中,但跟它對應的對象的核心功能可以說是毫無關系,還有很多類似的代碼,如權限驗證,調試輸出,事務處理等,也都是如此,這樣的話就不利于代碼的復用和管理了。

這時候AOP技術就應運而生了,它利用“橫切”技術,深入封裝對象的內部,并將那些影響了多個類的公共行為封裝到一個可重用模塊,并將其命名為'Aspect',即切面。所謂'切面',簡單說就是那些與業務無關,卻為業務模塊所共同調用的邏輯或責任封裝起來,便于減少系統的重復代碼,降低模塊之間的耦合度,并有利于后續的可操作性和可維護性。

那么AOP又是如何實現的呢?

答案是動態代理(關于代理會有另外篇章做詳細介紹,這里就不贅述了)。實現動態代理有兩種方式,一種是JDK動態代理,一種是CGLib動態代理。

那么分別使用兩種方式來做一個簡單的栗子。

先設計一個場景,假設我們有一個計算接口ICalculator和實現了該接口的計算器類CalculatorImpl。

public interface ICalculator { //加法運算 public int add(int a,int b); //減法 public int subtract(int a,int b); //乘法 public int multiply(int a,int b); //除法 public int devide(int a,int b);}

public class CalculatorImpl implements ICalculator{ @Override public int add(int a, int b) { return a + b; } @Override public int subtract(int a, int b) { return a - b; } @Override public int multiply(int a, int b) { return a * b; } @Override public int devide(int a, int b) { return a / b; }}

如何在不改動原來計算器類內部代碼的情況下記錄計算器各個方法使用的總次數呢?

有了動態代理后,其實就很簡單了,先創建一個類并實現InvocationHandler接口,覆蓋invoke方法,

public class TestHandler implements InvocationHandler { private Object targetObject; private int useTimes; //綁定委托對象,并返回代理類 public Object bind(Object targetObject){ this.targetObject = targetObject; return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //do something before(); Object result = method.invoke(targetObject,args); after(); return result; } private void before(){ System.out.println('we can do something before calculate.'); } private void after(){ useTimes++; System.out.println('已使用:'+useTimes+'次'); }}

別看代碼好像有點多,其實主要的方法就是invoke方法,里面的Object result = method.invoke(targetObject,args);相當于繼續用原來的參數執行原來方法。這里的before和after為自定義的函數,可以在目標代碼執行前后做一些我們想要做的事情,比如這里的使用次數統計。

在bind方法里,傳入目標代理對象,并返回一個代理類實例。接下來我們看看如何使用:

public class TestProxy { public static void main(String[] args) { TestHandler proxy = new TestHandler(); ICalculator calculator = (ICalculator)proxy.bind(new CalculatorImpl()); int result = calculator.add(1,2); System.out.println('result is:'+result); result = calculator.subtract(3,2); System.out.println('result is:'+result); result = calculator.multiply(4,6); System.out.println('result is:'+result); result = calculator.devide(6,2); System.out.println('result is:'+result); }}

我們先定義一個TestHandler,然后通過bind方法來獲得一個代理實例,之后我們就可以直接使用這個實例了。運行結果如下:

we can do something before calculate.已使用:1次result is:3we can do something before calculate.已使用:2次result is:1we can do something before calculate.已使用:3次result is:24we can do something before calculate.已使用:4次result is:3

這樣我們就實現了不修改CalculatorImpl內部代碼的情況下對代碼進行擴展。

接下來用CGLib的方式來實現一次。

先創建一個類來實現MethodInterceptor接口,并覆蓋intercept方法。其他代碼跟使用JDK代理大同小異,僅僅是獲取代理對象的過程有所差異。

public class CGLibProxy implements MethodInterceptor { private int useTimes; private Object target; public Object getInstance(Object target){ this.target=target; Enhancer enhancer =new Enhancer(); enhancer.setSuperclass(this.target.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { before(); Object result = methodProxy.invokeSuper(o,objects); after(); return result; } private void before(){ System.out.println('we can do something before calculate.'); } private void after(){ useTimes++; System.out.println('已使用:'+useTimes+'次'); }}

測試一下:

public class TestCGLibProxy { public static void main(String[] args) { CGLibProxy cgLibProxy = new CGLibProxy(); ICalculator calculator = (ICalculator) cgLibProxy.getInstance(new CalculatorImpl()); int result = calculator.add(1,2); System.out.println('result is:'+result); result = calculator.subtract(3,2); System.out.println('result is:'+result); result = calculator.multiply(4,6); System.out.println('result is:'+result); result = calculator.devide(6,2); System.out.println('result is:'+result); }}

運行結果如下:

we can do something before calculate.已使用:1次result is:3we can do something before calculate.已使用:2次result is:1we can do something before calculate.已使用:3次result is:24we can do something before calculate.已使用:4次result is:3

現在我們得到了同樣的結果。(需要導入兩個包,cglib-2.2.2.jar asm-3.3.jar)

兩種方法各有所長,JDK代理需要先設置一個接口,然后才能實現代理,這是它的缺點,也是它的優點,缺點是這樣會麻煩一點,而且無法對那些已經封裝好的,沒有實現接口的類進行代理,而CGLib代理的方式不需要使用接口。但也正是因為如此,JDK代理的方式僅僅攔截類中覆蓋接口的方法,而CGLib則會攔截類的所有方法調用。兩者各有利弊,所以需要具體情況具體分析。在Spring中也是混雜使用了兩種代理模式。

以上就是Java核心庫實現簡單的AOP的詳細內容,更多關于Java 實現aop的資料請關注好吧啦網其它相關文章!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
精品国产美女a久久9999| 中文无码日韩欧| 亚洲久久一区| 日韩二区三区在线观看| 欧美日韩亚洲一区在线观看| 国产精品久一| 91视频一区| 亚洲二区三区不卡| 亚洲另类av| 国产欧美日韩精品一区二区免费 | 日本va欧美va精品发布| 欧美亚洲网站| 日韩精品永久网址| 精品一区免费| 亚洲欧美成人综合| 国产精品任我爽爆在线播放| 91亚洲一区| 蜜桃视频在线观看一区| 国产情侣久久| 日本精品不卡| 中文字幕亚洲在线观看| 国产精品一区二区中文字幕| 日韩国产综合| 亚洲一区二区小说| 久久av资源| 特黄特色欧美大片| 亚洲精品裸体| 97欧美在线视频| 在线精品视频一区| 久久麻豆视频| 日韩视频在线一区二区三区 | 久久精品国产99久久| 人人爽香蕉精品| 久久婷婷国产| 在线亚洲一区| 精品久久福利| 鲁大师影院一区二区三区| 精品一区不卡| 亚洲精品激情| 成人羞羞在线观看网站| 四虎国产精品免费久久| 欧美aa在线观看| 亚洲免费毛片| 婷婷成人综合| 麻豆91精品视频| 亚洲中午字幕| 在线看片福利| 一区二区国产在线观看| 欧美xxxx中国| 国产色噜噜噜91在线精品| 激情欧美国产欧美| 精品一区视频| 中文字幕av一区二区三区人| 国产高潮在线| 国产精品66| 中文字幕日本一区二区| 亚洲福利精品| 国产96在线亚洲| 国产精品尤物| 日韩欧美久久| 日韩专区一卡二卡| 国产91一区| 久久av影视| 日韩精品久久久久久久软件91| 快播电影网址老女人久久| 国产精品chinese| 日韩av午夜在线观看| 视频在线观看91| 99热精品久久| 日韩av一区二区三区四区| 另类国产ts人妖高潮视频| 国产一区日韩欧美| 久久久久网站| 桃色av一区二区| 国产精品白丝一区二区三区| 日韩影院在线观看| 亚洲欧洲一区| 久久精品91| 亚洲精品.com| 新版的欧美在线视频| 精品国产乱码久久久久久1区2匹| 国产另类在线| 国产精久久久| 欧美日韩a区| 国产精品亚洲综合色区韩国| 国产三级精品三级在线观看国产| 日韩 欧美一区二区三区| 视频一区二区三区在线| 久久午夜精品| 日韩精品一级二级 | 7777精品| 欧美亚洲一级| 国产精品草草| 久久精品九色| 狂野欧美性猛交xxxx| 国产乱码精品一区二区三区四区 | 国产精品一区三区在线观看| 国产日韩欧美在线播放不卡| 青青草精品视频| 欧美日本久久| 久久亚洲黄色| 激情亚洲影院在线观看| jizzjizz中国精品麻豆| 久久裸体视频| 亚洲欧美日韩综合国产aⅴ| 视频一区在线视频| 亚洲精品大片| 国产精品片aa在线观看 | 高潮久久久久久久久久久久久久| 色综合五月天| 欧美69视频| 在线精品一区二区| 国产亚洲一区二区三区啪| 麻豆一区二区三| 今天的高清视频免费播放成人| 久久美女精品| 伊人久久一区| 国产精品久久乐| 欧美国产美女| 欧洲激情综合| 久热综合在线亚洲精品| 欧美日韩视频免费看| 国产一区二区三区四区二区 | 精品国产乱码久久久久久1区2匹| 日韩一区二区三区免费| 国产精品日韩| 国产乱码精品一区二区三区四区 | 久久九九精品| 免费在线看一区| 国产调教精品| 天堂8中文在线最新版在线| 好看不卡的中文字幕| 亚洲精品在线a| 国产精品成久久久久| re久久精品视频| 国产私拍福利精品视频二区| 国产拍在线视频| 激情欧美日韩一区| 日本不卡不码高清免费观看 | 欧美在线影院| 国产欧美日韩精品高清二区综合区 | 成人综合一区| 亚洲少妇诱惑| 久久av中文| 久久久一二三| 国产亚洲亚洲| 美女久久久久久| 国产一区欧美| 久久精品国产精品亚洲毛片| 神马午夜久久| 国产日韩视频在线| 亚洲调教视频在线观看| 国产精品一区二区99| 亚洲欧洲午夜| 日韩综合在线| 国产亚洲一卡2卡3卡4卡新区| 激情欧美一区二区三区| 欧美天堂在线| 亚洲激情婷婷| 黄色在线网站噜噜噜| 免费看日韩精品| 日韩国产欧美| 欧美国产三级| 国产一卡不卡| 亚洲天堂日韩在线| 国模 一区 二区 三区| 欧美精品不卡| 91麻豆精品| 亚洲精品精选| 久久国产高清| 黄色av一区| 999国产精品| 精品视频在线一区二区在线| 亚洲精品韩国| 亚洲国产不卡| 精品三级在线| 天堂俺去俺来也www久久婷婷| 久久亚洲国产| 在线看片国产福利你懂的| 国产伦一区二区三区| 天使萌一区二区三区免费观看| 三级小说欧洲区亚洲区| 国产精品99视频| 美女久久99| 欧美激情福利| 国产精品尤物| 97久久超碰| 日韩欧乱色一区二区三区在线| 亚洲一区不卡| 日韩午夜在线| 亚洲二区三区不卡| 亚洲调教视频在线观看| 天堂网av成人| 新版的欧美在线视频| 欧美少妇精品| 日韩免费一区| 日韩电影免费网站| 久久久成人网| 不卡av一区二区| 亚洲国产不卡|