日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java程序员从笨鸟到菜鸟之(七十三)细谈Spring(五)spring之AOP底层大揭秘

發布時間:2025/3/21 java 76 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java程序员从笨鸟到菜鸟之(七十三)细谈Spring(五)spring之AOP底层大揭秘 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

眾所周知,Java是面向對象語言的有力代表,提到java我們就會立即想到面向對象,提到面向對象我們就會想到java然而面向對象也并非完美無缺的,它更注重于對象層次結構方面的東西,對于如何更好的管理對象行為內部結構,還存在著些許不足。那么我們如何使這個問題的得到更完美的解決呢?答案就是AOP

????????AOPAspect-Oriented?ProgrammingAOPOOP的補充,是GOF的延續。我們知道設計模式是對于面向對象設計中經驗的總結,它孜孜不斷追求的就是調用者與被調用者之間的解耦。有了設計模式我們可以更有效的利用面向對象的特性,使得整個軟件設計更加靈活、優雅。但是設計模式是基于面向對象的思想而形成的,更多的時候關注的是對象層次的東西,在解決對象行為內部問題方面卻有些不足。AOP的出現恰恰就是對面向對象思想做出了完美的補充。

?????說到AOP,我們就不得不來提一下軟件的縱向和橫向問題。從縱向結構來看就是我們軟件系統的各個模塊,它主要負責處理我們的核心業務(例如商品訂購、購物車查看);而從橫向結構來看,我們幾乎每個系統又包含一些公共模塊(例如權限、日志模塊等)。這些公共模塊分布于我們各個核心業務之中(例如訂購和查看商品明細的過程都需要檢查用戶權限、記錄系統日志等)。這樣一來不僅在開發過程中要處處關注公共模塊的處理而且開發后維護起來也是十分麻煩。而有了AOP之后將應用程序中的商業邏輯同對其提供支持的通用服務進行分離,使得開發人員可以更多的關注核心業務開發。?

? ? ? ? ? ? ? ? ? ? ?

下面我們就以一個簡單的例子來看一下AOP吧!比如說,我們現在要開發的一個應用里面有很多的業務方法,但是,我們現在要對這個方法的執行做全面監控,或部分監控.也許我們就會在要一些方法前去加上一條日志記錄,我們寫個例子看看我們最簡單的解決方案
我們先寫一個接口IHello.java代碼如下:

[java]?view plaincopy print?
  • public?interface?IHello{??
  • ?/**?*//**?
  • ??*?假設這是一個業務方法?
  • ?*@param?name?
  • ?*/??
  • ?void?sayHello(String?name);??
  • ?}??


  • 里面有個方法,用于輸入"Hello"?加傳進來的姓名;我們去寫個類實現IHello接口


    [java]?view plaincopy print?
  • public?class?Helloimplements?IHello{??
  • ??
  • public?void?sayHello(String?name){??
  • System.out.println("Hello"?+?name);??
  • }??
  • }??


  • 現在我們要為這個業務方法加上日志記錄的業務 , 我們在不改變原代碼的情況下 , 我們會去怎么做呢 ? 也許 , 你會去寫一個類去實現 IHello 接口 , 并依賴 Hello 這個類 . 代碼如下 :

    [java]?view plaincopy print?
  • public?class?HelloProxyimplements?IHello{??
  • ?private?IHello?hello;??
  • ???
  • ?public?HelloProxy(IHello?hello){??
  • ?this.hello=?hello;??
  • ??}??
  • ???
  • public?void?sayHello(String?name){??
  • ?Logger.logging(Level.DEBUGE,"sayHello?method?start.");??
  • ?hello.sayHello(name);??
  • ?Logger.logging(Level.INFO,"sayHello?method?end!");??
  • ??
  • ?}??
  • }??


  • ??????從上面的代碼我們可以看出,hello對象是被HelloProxy這個所謂的代理態所創建的.這樣,如果我們以后要把日志記錄的功能去掉.那我們只要把得到hello對象的的具體實現改為Hello的就可以。上面的代碼?就是對AOP的最簡單的視線,但是我們接下來想,如果我們要在很多業務邏輯之前加日志的話,那么,我們是不是要去寫很多個HelloProxy這樣的類呢.沒錯,是的.其實也是一種很麻煩的事.jdk1.3以后.jdk跟我們提供了一個API?java.lang.reflect.InvocationHandler的類.?這個類可以讓我們在JVM調用某個類的方法時動態的為些方法做些什么事.讓我們把以上的代碼改一下來看看效果.



    同樣,我們寫一個IHello的接口和一個Hello的實現類.在接口中.我們定義兩個方法;代碼如下?:

    IHello.java

    [java]?view plaincopy print?
  • package?sinosoft.dj.aop.proxyaop;??
  • ???
  • ?public?interface?IHello{??
  • ?/**?*//**?
  • ??*?業務處理A方法?
  • ??*@param?name?
  • ?*/??
  • ?void?sayHello(String?name);??
  • ?/**?*//**?
  • ?*?業務處理B方法?
  • ?*@param?name?
  • */??
  • void?sayGoogBye(String?name);??
  • }??




  • Hello.java

    [java]?view plaincopy print?
  • package?sinosoft.dj.aop.proxyaop;??
  • ???
  • ?public?class?Helloimplements?IHello{??
  • ???
  • ?public?void?sayHello(String?name){??
  • ??System.out.println("Hello"?+?name);??
  • ??}??
  • ?public?void?sayGoogBye(String?name){??
  • ?System.out.println(name+"?GoodBye!");??
  • ?}??
  • }??



  • 我們一樣的去寫一個代理類.只不過.讓這個類去實現java.lang.reflect.InvocationHandler接口,代碼如下:

    [java]?view plaincopy print?
  • package?sinosoft.dj.aop.proxyaop;??
  • ???
  • ?import?java.lang.reflect.InvocationHandler;??
  • ?import?java.lang.reflect.Method;??
  • import?java.lang.reflect.Proxy;??
  • ???
  • ?public?class?DynaProxyHelloimplements?InvocationHandler{??
  • ???
  • ?/**?*//**?
  • ?*?要處理的對象(也就是我們要在方法的前后加上業務邏輯的對象,如例子中的Hello)?
  • */??
  • private?Object?delegate;??
  • ??
  • /**?*//**?
  • ?*?動態生成方法被處理過后的對象?(寫法固定)?
  • ?*?
  • ?*@param?delegate?
  • ?*@param?proxy?
  • ?*@return?
  • */??
  • public?Object?bind(Object?delegate){??
  • this.delegate=?delegate;??
  • return?Proxy.newProxyInstance(??
  • this.delegate.getClass().getClassLoader(),this.delegate??
  • ?.getClass().getInterfaces(),this);??
  • ?}??
  • /**?*//**?
  • ?*?要處理的對象中的每個方法會被此方法送去JVM調用,也就是說,要處理的對象的方法只能通過此方法調用?
  • ?*?此方法是動態的,不是手動調用的?
  • */??
  • public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)??
  • throws?Throwable{??
  • ?Object?result=?null;??
  • try?{??
  • //執行原來的方法之前記錄日志??
  • ?Logger.logging(Level.DEBUGE,?method.getName()+?"?Method?end?.");??
  • ??
  • //JVM通過這條語句執行原來的方法(反射機制)??
  • ?result=?method.invoke(this.delegate,?args);??
  • //執行原來的方法之后記錄日志??
  • ?Logger.logging(Level.INFO,?method.getName()+?"?Method?Start!");??
  • ?}?catch?(Exception?e){??
  • ?e.printStackTrace();??
  • ?}??
  • //返回方法返回值給調用者??
  • ?return?result;??
  • }?}??



  • ? ? ? 從上面的例子我們看出.只要你是采用面向接口編程,那么,你的任何對象的方法執行之前要加上記錄日志的操作都是可以的.(DynaPoxyHello)自動去代理執行被代理對象(Hello)中的每一個方法,一個java.lang.reflect.InvocationHandler接口就把我們的代理對象和被代理對象解藕了


    from:?http://blog.csdn.net/csh624366188/article/details/7650150

    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的Java程序员从笨鸟到菜鸟之(七十三)细谈Spring(五)spring之AOP底层大揭秘的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。