JAVA動態(tài)代理

Spring AOP功能最基本的技術(shù)要點為動態(tài)代理吧恃。
當(dāng)下Java主要有兩種動態(tài)代理方式

  • 基于接口的JDK動態(tài)代理
  • 基于類CGLib動態(tài)代理

JDK動態(tài)代理

JDK動態(tài)代理是在運行時根據(jù)類的接口生成新的實現(xiàn)類玖姑,讓新的實現(xiàn)類對已有對象進行代理浇雹。

首先聲明兩個接口

    public interface Machine {
      public void start();
    }
    public interface Car extends Machine {
      public void drive();
    }

實現(xiàn)類

    public class Bus implements Car {

      @Override
      public void drive() {
        System.out.println("老司機開車?yán)玻?);
      }

      @Override
      public void start() {
        System.out.println("開始:炕酢返劲!");

      }

    }

代理處理類:

    public class JdkProxy implements InvocationHandler {
      private Object obj;

      @SuppressWarnings( "unchecked" )
      public <T> T getProxy( T obj ) {
        this.obj = obj;
        return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
      }

      @Override
      public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable {
        System.out.println("動態(tài)代理開始病苗!");
        Object reVal = method.invoke(obj, args);
        System.out.println("動態(tài)代理結(jié)束惩嘉!");
        return reVal;
      }

    }

Proxy.newProxyInstance是使用當(dāng)前類的接口生成代理對象。
InvocationHandler 為代理的處理接口乱灵。

Main函數(shù)

    public static void main( String[] args ) {
        Car car = new Bus();
        JdkProxy jdkProxy = new JdkProxy();
        Car proxyCar = jdkProxy.getProxy(car);
        proxyCar.start();
        proxyCar.drive();
    }
結(jié)果

CGLib動態(tài)代理

CGLib是生成當(dāng)前類的子類忆某,讓子類對父類進行代理。

引入Jar包

    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>3.2.4</version>
    </dependency>

被代理的類

    public class Student {
      public void sayHello() {
        System.out.println("hello");
      }
    }

代理處理及代理對象生成

    public class StudentProxy implements MethodInterceptor {
      private Enhancer enhancer;

      public <T> T getProxy( Class<T> clazz ) {
        enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);

        return (T) enhancer.create();
      }

      @Override
      public Object intercept( Object object, Method method, Object[] args, MethodProxy proxy ) throws Throwable {
        System.out.println("before");
        proxy.invokeSuper(object, args);
        System.out.println("after");
        return null;
      }

    }

Main函數(shù):

    public static void main( String[] args ) {
        StudentProxy proxy = new StudentProxy();
        Student student = proxy.getProxy(Student.class);
        student.sayHello();
    }

結(jié)果:

結(jié)果

簡單測試兩種代理方式的性能:

    /**
     * @author : Zak
     * @date : 2017年1月17日 上午11:52:23
     * @version : 2017年1月17日 Zak 首次創(chuàng)建
     */
    public class Main {

      public static void main( String[] args ) {
        Bus bus = new Bus();
        JdkProxy jdkProxy = new JdkProxy();
        CglibProxy cglibProxy = new CglibProxy();
        long jdkproxyInitTime = 0, cglibproxyinitTime = 0, jdkInvokeTime = 0, cglibInvokeTime = 0, startTime = 0;
        for( int i = 0; i < 1000001; i++ ) {
          System.out.println(i);
          switch(i % 2) {
            case 0:// JDKProxy
              startTime = System.currentTimeMillis();
              Car car = jdkProxy.getProxy(bus);
              jdkproxyInitTime += System.currentTimeMillis() - startTime;

              startTime = System.currentTimeMillis();
              car.drive();
              jdkInvokeTime += System.currentTimeMillis() - startTime;

              break;
            case 1:// CGLib

              startTime = System.currentTimeMillis();
              Car car1 = cglibProxy.getProxy(Bus.class);
              cglibproxyinitTime += System.currentTimeMillis() - startTime;

              startTime = System.currentTimeMillis();
              car1.drive();
              cglibInvokeTime += System.currentTimeMillis() - startTime;

          }
        }
        System.out.println("~~~~~~~~~~~~~~~~~~~~~Result~~~~~~~~~~~~~~~~~~~~~~~~~~");
        System.out.println("JDKInitTtime:" + jdkproxyInitTime);
        System.out.println("jdkInvokeTime:" + jdkInvokeTime);
        System.out.println("jdkInvokeTime:" + cglibproxyinitTime);
        System.out.println("cglibInvokeTime:" + cglibInvokeTime);
      }
    }
測試結(jié)果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末阔蛉,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子癞埠,更是在濱河造成了極大的恐慌状原,老刑警劉巖聋呢,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異颠区,居然都是意外死亡削锰,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門毕莱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來器贩,“玉大人,你說我怎么就攤上這事朋截∮忌裕” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵部服,是天一觀的道長唆姐。 經(jīng)常有香客問我,道長廓八,這世上最難降的妖魔是什么奉芦? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮剧蹂,結(jié)果婚禮上声功,老公的妹妹穿的比我還像新娘。我一直安慰自己宠叼,他們只是感情好先巴,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著车吹,像睡著了一般筹裕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上窄驹,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天朝卒,我揣著相機與錄音,去河邊找鬼乐埠。 笑死抗斤,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丈咐。 我是一名探鬼主播瑞眼,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼棵逊!你這毒婦竟也來了伤疙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎徒像,沒想到半個月后黍特,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡锯蛀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年灭衷,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旁涤。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡翔曲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出劈愚,到底是詐尸還是另有隱情瞳遍,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布造虎,位于F島的核電站傅蹂,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏算凿。R本人自食惡果不足惜份蝴,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望氓轰。 院中可真熱鬧婚夫,春花似錦、人聲如沸署鸡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽靴庆。三九已至时捌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炉抒,已是汗流浹背奢讨。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留焰薄,地道東北人拿诸。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像塞茅,于是被迫代替她去往敵國和親亩码。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容