一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - java動態代理和cglib動態代理示例分享

java動態代理和cglib動態代理示例分享

2019-11-15 14:46java教程網 JAVA教程

這篇文章主要介紹了java動態代理和cglib動態代理示例,JDK1.3之后,Java提供了動態代理的技術,允許開發者在運行期間創建接口的代理實例,下面我們使用示例學習一下

java動態代理類可以分為兩種。 

靜態代理:由程序員創建或特定工具自動生成源代碼,再對其編譯。在程序運行前,代理類的.class文件就已經存在了。 

動態代理:在程序運行時,運用反射機制動態創建而成。


一、首先我們進行java動態代理的演示。

現在我們有一個簡單的業務接口Saying,如下:

復制代碼代碼如下:

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

 

一個簡單的實現類SayingImpl,如下:

復制代碼代碼如下:

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 + ":我的意思是,我們要努力建設和諧社會!");
    }
}

 

我們要實現的是,在sayHello和talking之前和之后分別動態植入處理。

JDK動態代理主要用到java.lang.reflect包中的兩個類:Proxy和InvocationHandler.

InvocationHandler是一個接口,通過實現該接口定義橫切邏輯,并通過反射機制調用目標類的代碼,動態的將橫切邏輯和業務邏輯編織在一起。

Proxy利用InvocationHandler動態創建一個符合某一接口的實例,生成目標類的代理對象。

如下,我們創建一個InvocationHandler實例:

 

復制代碼代碼如下:


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 {
        //目標方法前執行
        System.out.println("——————————————————————————");
        System.out.println("下一位請登臺發言!");
        //目標方法調用
        Object obj = method.invoke(target, args);
        //目標方法后執行
        System.out.println("大家掌聲鼓勵!");
        return obj;
    }
}

 

下面是測試:

 

復制代碼代碼如下:

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

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

 

運行情況如下:

 

復制代碼代碼如下:

——————————————————————————
下一位請登臺發言!
小明:大家好啊!
大家掌聲鼓勵!
——————————————————————————
下一位請登臺發言!
小麗:我的意思是,我們要努力建設和諧社會!
大家掌聲鼓勵!

 

使用JDK動態代理有一個很大的限制,就是它要求目標類必須實現了對應方法的接口,它只能為接口創建代理實例。我們在上文測試類中的Proxy的newProxyInstance方法中可以看到,該方法第二個參數便是目標類的接口。如果該類沒有實現接口,這就要靠cglib動態代理了。

CGLib采用非常底層的字節碼技術,可以為一個類創建一個子類,并在子類中采用方法攔截的技術攔截所有父類方法的調用,并順勢植入橫切邏輯。

二、接下來我們進行cglib動態代理的演示。

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

我們首先創建一個代理創建器CglibProxy:

 

復制代碼代碼如下:


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) {
        //設置需要創建的子類
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        //通過字節碼技術動態創建子類實例
        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("下一位請登臺發言!");
        //目標方法調用
        Object result = proxy.invokeSuper(obj, args);
        //目標方法后執行
        System.out.println("大家掌聲鼓勵!");
        return result;
    }    
}

 

然后進行測試:

 

復制代碼代碼如下:


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

 

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

 

結果與JDK動態代理沒有任何區別。

JDK動態代理和CGLib動態代理都是運行時增強,通過將橫切代碼植入代理類的方式增強。與此不同的是AspectJ,它能夠在通過特殊的編譯器在編譯時期將橫切代碼植入增強,這樣的增強處理在運行時候更有優勢,因為JDK動態代理和CGLib動態代理每次運行都需要增強。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 紧身裙女教师波多野结衣 | 网站在线播放 | 精品亚洲综合在线第一区 | 精品国产欧美一区二区三区成人 | 国产高清路线一路线二2022 | 513热点网深夜影院影院诶 | 国产情侣视频观看 | 国产小情侣自拍 | 无码日韩精品一区二区免费 | 波多野结衣一区 | 日本日日黄 | 高清毛片一区二区三区 | 国产亚洲精品一区二区在线观看 | 亚洲视频一区二区在线观看 | 国产成人福利免费观看 | 美女自插| 好大夫在线个人空间 | 国色天香社区在线视频播放 | 99热com| 欧美乱子伦xxxx12在线 | 青草园网站在线观看 | 俄罗斯女同和女同xx | 欧美一级特黄刺激大片视频 | 亚洲琪琪 | 日本中文字幕一区二区有码在线 | 亚洲 欧美 国产 日韩 字幕 | 欧美精品国产一区二区 | 五月天在线视频观看 | 日本视频一区在线观看免费 | www国产精品 | 国产精品视频免费观看 | 岛国免费大片 | 小浪妇奶真大水多 | 午夜爱爱爱爱爽爽爽视频网站 | 热99精品只有里视频最新 | 国产福利微拍精品一区二区 | 日韩成人影视 | 国产a一级毛片爽爽影院 | 久久亚洲精品AV无码四区 | 2022天堂岛日产| 亚洲视频在线免费看 |