最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理示例分享

 更新時(shí)間:2014年03月23日 11:34:16   作者:  
這篇文章主要介紹了java動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理示例,JDK1.3之后,Java提供了動(dòng)態(tài)代理的技術(shù),允許開發(fā)者在運(yùn)行期間創(chuàng)建接口的代理實(shí)例,下面我們使用示例學(xué)習(xí)一下

java動(dòng)態(tài)代理類可以分為兩種。

靜態(tài)代理:由程序員創(chuàng)建或特定工具自動(dòng)生成源代碼,再對(duì)其編譯。在程序運(yùn)行前,代理類的.class文件就已經(jīng)存在了。

動(dòng)態(tài)代理:在程序運(yùn)行時(shí),運(yùn)用反射機(jī)制動(dòng)態(tài)創(chuàng)建而成。


一、首先我們進(jìn)行java動(dòng)態(tài)代理的演示。

現(xiàn)在我們有一個(gè)簡(jiǎn)單的業(yè)務(wù)接口Saying,如下:

復(fù)制代碼 代碼如下:

package testAOP;
public interface Saying {
public void sayHello(String name);   
public void talking(String name);
}

一個(gè)簡(jiǎn)單的實(shí)現(xiàn)類SayingImpl,如下:

復(fù)制代碼 代碼如下:

package testAOP;
public class SayingImpl implements Saying {
    @Override
    public void sayHello(String name) {
        // TODO Auto-generated method stub
        System.out.println(name + ":大家好?。?);
    }
    @Override
    public void talking(String name) {
        // TODO Auto-generated method stub
        System.out.println(name + ":我的意思是,我們要努力建設(shè)和諧社會(huì)!");
    }
}

我們要實(shí)現(xiàn)的是,在sayHello和talking之前和之后分別動(dòng)態(tài)植入處理。

JDK動(dòng)態(tài)代理主要用到j(luò)ava.lang.reflect包中的兩個(gè)類:Proxy和InvocationHandler.

InvocationHandler是一個(gè)接口,通過實(shí)現(xiàn)該接口定義橫切邏輯,并通過反射機(jī)制調(diào)用目標(biāo)類的代碼,動(dòng)態(tài)的將橫切邏輯和業(yè)務(wù)邏輯編織在一起。

Proxy利用InvocationHandler動(dòng)態(tài)創(chuàng)建一個(gè)符合某一接口的實(shí)例,生成目標(biāo)類的代理對(duì)象。

如下,我們創(chuàng)建一個(gè)InvocationHandler實(shí)例:

復(fù)制代碼 代碼如下:

package testAOP;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {

    private Object target;
    MyInvocationHandler(Object target){
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        //目標(biāo)方法前執(zhí)行
        System.out.println("——————————————————————————");
        System.out.println("下一位請(qǐng)登臺(tái)發(fā)言!");
        //目標(biāo)方法調(diào)用
        Object obj = method.invoke(target, args);
        //目標(biāo)方法后執(zhí)行
        System.out.println("大家掌聲鼓勵(lì)!");
        return obj;
    }
}

下面是測(cè)試:

復(fù)制代碼 代碼如下:

package testAOP;
import java.lang.reflect.Proxy;
public class JDKProxyTest {

    public static void main(String[] args) {
        // 希望被代理的目標(biāo)業(yè)務(wù)類
        Saying target = new SayingImpl();
        // 將目標(biāo)類和橫切類編織在一起
        MyInvocationHandler handler = new MyInvocationHandler(target);
        // 創(chuàng)建代理實(shí)例
        Saying proxy = (Saying) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),//目標(biāo)類的類加載器
                target.getClass().getInterfaces(),//目標(biāo)類的接口
                handler);//橫切類
        proxy.sayHello("小明");
        proxy.talking("小麗");
    }
}

運(yùn)行情況如下:

復(fù)制代碼 代碼如下:

——————————————————————————
下一位請(qǐng)登臺(tái)發(fā)言!
小明:大家好??!
大家掌聲鼓勵(lì)!
——————————————————————————
下一位請(qǐng)登臺(tái)發(fā)言!
小麗:我的意思是,我們要努力建設(shè)和諧社會(huì)!
大家掌聲鼓勵(lì)!

使用JDK動(dòng)態(tài)代理有一個(gè)很大的限制,就是它要求目標(biāo)類必須實(shí)現(xiàn)了對(duì)應(yīng)方法的接口,它只能為接口創(chuàng)建代理實(shí)例。我們?cè)谏衔臏y(cè)試類中的Proxy的newProxyInstance方法中可以看到,該方法第二個(gè)參數(shù)便是目標(biāo)類的接口。如果該類沒有實(shí)現(xiàn)接口,這就要靠cglib動(dòng)態(tài)代理了。

CGLib采用非常底層的字節(jié)碼技術(shù),可以為一個(gè)類創(chuàng)建一個(gè)子類,并在子類中采用方法攔截的技術(shù)攔截所有父類方法的調(diào)用,并順勢(shì)植入橫切邏輯。

二、接下來我們進(jìn)行cglib動(dòng)態(tài)代理的演示。

首先我們需要導(dǎo)包,我用的包是cglib-nodep-2.1_3.jar。

我們首先創(chuàng)建一個(gè)代理創(chuàng)建器CglibProxy:

復(fù)制代碼 代碼如下:

package testAOP.cglib;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor{

    Enhancer enhancer = new Enhancer();
    public Object getProxy(Class clazz) {
        //設(shè)置需要?jiǎng)?chuàng)建的子類
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        //通過字節(jié)碼技術(shù)動(dòng)態(tài)創(chuàng)建子類實(shí)例
        return enhancer.create();
    }
    @Override
    public Object intercept(Object obj, Method method, Object[] args,
            MethodProxy proxy) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("——————————————————————————");
        System.out.println("下一位請(qǐng)登臺(tái)發(fā)言!");
        //目標(biāo)方法調(diào)用
        Object result = proxy.invokeSuper(obj, args);
        //目標(biāo)方法后執(zhí)行
        System.out.println("大家掌聲鼓勵(lì)!");
        return result;
    }   
}

然后進(jìn)行測(cè)試:

復(fù)制代碼 代碼如下:

package testAOP.cglib;
import testAOP.Saying;
import testAOP.SayingImpl;
public class CglibProxyTest {

    public static void main(String[] args) {
        CglibProxy proxy = new CglibProxy();
        //通過動(dòng)態(tài)生成子類的方式創(chuàng)建代理類
        Saying target = (Saying) proxy.getProxy(SayingImpl.class);
        target.sayHello("小明");
        target.talking("小麗");
    }
}

結(jié)果與JDK動(dòng)態(tài)代理沒有任何區(qū)別。

JDK動(dòng)態(tài)代理和CGLib動(dòng)態(tài)代理都是運(yùn)行時(shí)增強(qiáng),通過將橫切代碼植入代理類的方式增強(qiáng)。與此不同的是AspectJ,它能夠在通過特殊的編譯器在編譯時(shí)期將橫切代碼植入增強(qiáng),這樣的增強(qiáng)處理在運(yùn)行時(shí)候更有優(yōu)勢(shì),因?yàn)镴DK動(dòng)態(tài)代理和CGLib動(dòng)態(tài)代理每次運(yùn)行都需要增強(qiáng)。

相關(guān)文章

  • MyBatis源碼分析之日志logging詳解

    MyBatis源碼分析之日志logging詳解

    這篇文章主要給大家介紹了關(guān)于MyBatis源碼分析之日志logging的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 基于Java Swing制作一個(gè)Pong小游戲

    基于Java Swing制作一個(gè)Pong小游戲

    《Pong》是美國(guó)雅達(dá)利公司(ATARI)開發(fā)的視頻游戲,該作模擬了兩個(gè)打乒乓球的人,就是在兩條線中間有一個(gè)點(diǎn)在動(dòng),操縱器就是一個(gè)搖桿上有一個(gè)按鈕的那種。本文就來用Java Swing制作一個(gè)Pong小游戲吧
    2023-01-01
  • SpringBoot關(guān)于自動(dòng)注入mapper為空的坑及解決

    SpringBoot關(guān)于自動(dòng)注入mapper為空的坑及解決

    這篇文章主要介紹了SpringBoot關(guān)于自動(dòng)注入mapper為空的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 基于Maven的pom.xml文件詳解

    基于Maven的pom.xml文件詳解

    下面小編就為大家?guī)硪黄贛aven的pom.xml文件詳解。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • 剖析Java中在Collection集合中使用contains和remove為什么要重寫equals

    剖析Java中在Collection集合中使用contains和remove為什么要重寫equals

    這篇文章主要介紹了Collection集合的contains和remove方法詳解remove以及相關(guān)的經(jīng)驗(yàn)技巧,通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • java對(duì)指定目錄下文件讀寫操作介紹

    java對(duì)指定目錄下文件讀寫操作介紹

    本文將詳細(xì)介紹java對(duì)指定目錄下文件的讀寫功能實(shí)現(xiàn),需要的朋友可以參考下
    2012-11-11
  • Spring Boot CLI安裝教程

    Spring Boot CLI安裝教程

    Spring Boot是一個(gè)命令行工具,用于使用Spring進(jìn)行快速原型搭建。本文重點(diǎn)給大家介紹Spring Boot CLI安裝教程,感興趣的朋友參考下吧
    2017-08-08
  • Java中bcrypt算法實(shí)現(xiàn)密碼加密的方法步驟

    Java中bcrypt算法實(shí)現(xiàn)密碼加密的方法步驟

    我們可以在Spring Boot和SSM中實(shí)現(xiàn)密碼加密,使用bcrypt算法可以保障密碼的安全性,并且減少了手動(dòng)編寫哈希函數(shù)的工作量,本文就來詳細(xì)的介紹一下,感興趣的可以了解一下
    2023-08-08
  • Scala異常處理的方法深入分析

    Scala異常處理的方法深入分析

    Scala是一種多范式的編程語(yǔ)言,支持面向?qū)ο蠛秃瘮?shù)式編程。Scala也支持異常處理,即在程序運(yùn)行過程中發(fā)生意外或錯(cuò)誤時(shí),采取相應(yīng)的措施
    2023-04-04
  • idea配置SVN的教程

    idea配置SVN的教程

    文章介紹了如何安裝和配置TortoiseSVN以及在IntelliJ?IDEA中配置SVN,首先,安裝TortoiseSVN時(shí)需要選擇與電腦配置相匹配的版本,并確保安裝命令行客戶端工具,其次,在IntelliJ?IDEA中配置SVN時(shí),需要指定SVN可執(zhí)行文件的路徑
    2025-01-01

最新評(píng)論

措美县| 裕民县| 和静县| 光山县| 大宁县| 昭觉县| 汤原县| 武安市| 东明县| 西丰县| 云和县| 禄劝| 新龙县| 依安县| 崇仁县| 哈巴河县| 榆中县| 吉林省| 冕宁县| 古丈县| 景泰县| 汾西县| 黔东| 丰镇市| 五常市| 商洛市| 铅山县| 邢台市| 北流市| 东光县| 昭平县| 梧州市| 石台县| 怀来县| 漯河市| 永泰县| 广河县| 桓台县| 长治市| 华安县| 芜湖县|