Java代理模式是什么

本篇內(nèi)容介紹了“Java代理模式是什么”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

成都創(chuàng)新互聯(lián)公司客戶idc服務(wù)中心,提供成都服務(wù)器托管、成都服務(wù)器、成都主機(jī)托管、成都雙線服務(wù)器等業(yè)務(wù)的一站式服務(wù)。通過各地的服務(wù)中心,我們向成都用戶提供優(yōu)質(zhì)廉價(jià)的產(chǎn)品以及開放、透明、穩(wěn)定、高性價(jià)比的服務(wù),資深網(wǎng)絡(luò)工程師在機(jī)房提供7*24小時(shí)標(biāo)準(zhǔn)級(jí)技術(shù)保障。

Java 代理模式

什么是代理

代理是一種設(shè)計(jì)模式,它的核心思想,是將對(duì)目標(biāo)的訪問轉(zhuǎn)移到代理對(duì)象上。這樣做的好處就是,目標(biāo)對(duì)象在不改變代碼的情況下,可以通過代理對(duì)象加一些額外的功能。這是一種編程思想,在不改變?cè)写a的情況下,通過代理增加一些擴(kuò)展功能。

代理過程如圖所示,用戶訪問代理對(duì)象,代理對(duì)象通過訪問目標(biāo)對(duì)象,來達(dá)到用戶訪問目標(biāo)對(duì)象的目的,

Java代理模式是什么

代理模式包含一下三個(gè)角色:

  • ISubject:接口對(duì)象,該接口是對(duì)象和它的代理共用的接口。

  • TargetSubject:目標(biāo)對(duì)象,是實(shí)現(xiàn)抽象主題接口的類。

  • Proxy:代理角色,內(nèi)部含有對(duì)目標(biāo)對(duì)象TargetSubject的引用,從而可以操作真實(shí)對(duì)象。代理對(duì)象提供與目標(biāo)對(duì)象相同的接口,以便在任何時(shí)刻都能代替目標(biāo)對(duì)象。同時(shí),代理對(duì)象可以在執(zhí)行目標(biāo)對(duì)象操作時(shí),附加其他的操作,相當(dāng)于對(duì)真實(shí)對(duì)象進(jìn)行封裝。

常見的代理模式分為靜態(tài)代理和動(dòng)態(tài)代理,動(dòng)態(tài)代理在Java中的實(shí)現(xiàn)分為JDK動(dòng)態(tài)代理和cglib代理。

靜態(tài)代理

在之前已經(jīng)說過,在代理模式中有三個(gè)角色,一是目標(biāo)接口,二是目標(biāo)對(duì)象,三是代理對(duì)象。

現(xiàn)在以具體代碼來實(shí)現(xiàn),首先是目標(biāo)接口如下:

 public interface IBlogService {

    void writeBlog();
}

目標(biāo)對(duì)象實(shí)現(xiàn)了目標(biāo)接口,代碼如下:

public class BlogService implements IBlogService {

    @Override
    public void writeBlog() {
        System.out.println("i'm writing...");
    }
}

靜態(tài)代理對(duì)象,通過構(gòu)造方法獲取到目標(biāo)對(duì)象,并實(shí)現(xiàn)了目標(biāo)接口,在目標(biāo)接口的方法里調(diào)用了目標(biāo)對(duì)象的方法,代碼如下:

public class BlogStaticProxy implements IBlogService{
    private IBlogService blogService;

    public BlogStaticProxy(IBlogService blogService) {
        this.blogService = blogService;
    }

    @Override
    public void writeBlog() {
        System.out.println("start writing...");
        blogService.writeBlog();
        System.out.println("end writing...");
    }
}

測(cè)試:

public class TestStaticProxy {

    public static void main(String[] args) {
        IBlogService target = new BlogService();
        BlogStaticProxy proxy = new BlogStaticProxy(target);
        proxy.write();
    }
}

start writing…

i’m writing…

end writing…

靜態(tài)代理,在不修改目標(biāo)對(duì)象的情況下,可以通過代理對(duì)象做額外的擴(kuò)展功能。但靜態(tài)方法不是很靈活,如果目標(biāo)接口的代碼修改,目標(biāo)對(duì)象和代理對(duì)象都需要修改。

動(dòng)態(tài)代理在一定程度上避免這種情況,動(dòng)態(tài)代理不需要代理對(duì)象實(shí)現(xiàn)目標(biāo)接口,并且上在java 虛擬機(jī)的內(nèi)存中動(dòng)態(tài)的生成代理對(duì)象

Jdk動(dòng)態(tài)對(duì)象

Jdk的動(dòng)態(tài)代理由Proxy這個(gè)類來生成,它有三個(gè)參數(shù):

  • ClassLoader loader,:指定當(dāng)前目標(biāo)對(duì)象使用類加載器,獲取加載器的方法是固定的

  • Class<?>[] interfaces,:目標(biāo)對(duì)象實(shí)現(xiàn)的接口的類型,使用泛型方式確認(rèn)類型

  • InvocationHandler h:事件處理,執(zhí)行目標(biāo)對(duì)象的方法時(shí),會(huì)觸發(fā)事件處理器的方法,會(huì)把當(dāng)前執(zhí)行目標(biāo)對(duì)象的方法作為參數(shù)傳入

 public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException
    {

    }

Jdk的動(dòng)態(tài)代理代碼如下:

 public class JdkBlogProxyFactory {

    private Object target;

    public JdkBlogProxyFactory(Object target) {
        this.target = target;
    }

    public Object newInstance() {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    System.out.println("start writing");
                    Object o = method.invoke(target, args);
                    System.out.println("end writing");
                    return o;
                });
    }
}

測(cè)試類:

public class TestJdkProxy {
    public static void main(String[] args) {

        IBlogService target = new BlogService();

        System.out.println(target.getClass());

        // 給目標(biāo)對(duì)象,創(chuàng)建代理對(duì)象
        IBlogService proxy = (IBlogService) new JdkBlogProxyFactory(target).newInstance();
        // class $Proxy0   內(nèi)存中動(dòng)態(tài)生成的代理對(duì)象
        System.out.println(proxy.getClass());

        // 執(zhí)行方法   【代理對(duì)象】
        proxy.writeBlog();
    }
}

控制臺(tái)打印如下:

class com.forezp.proxy.BlogService
class com.sun.proxy.$Proxy0
start writing
i'm writing...
end writing

CGLib動(dòng)態(tài)代理

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

CglibBlogFactory代理工廠類如下:

public class CglibBlogFactory implements MethodInterceptor {

    private Object target;

    public CglibBlogFactory(Object target) {
        this.target = target;
    }

    //給目標(biāo)對(duì)象創(chuàng)建一個(gè)代理對(duì)象
    public Object getProxyInstance() {
        //1.工具類
        Enhancer en = new Enhancer();
        //2.設(shè)置父類
        en.setSuperclass(target.getClass());
        //3.設(shè)置回調(diào)函數(shù)
        en.setCallback(this);
        //4.創(chuàng)建子類(代理對(duì)象)
        return en.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("start writing...");
        //執(zhí)行目標(biāo)對(duì)象的方法
        Object returnValue = method.invoke(target, objects);
        System.out.println("end writing...");
        return returnValue;
    }
}

測(cè)試類:

public class TestCglib {

    public static void main(String[] args) {
        IBlogService target = new BlogService();
        //代理對(duì)象
        IBlogService proxy = (IBlogService) new CglibBlogFactory(target).getProxyInstance();
        //執(zhí)行代理對(duì)象的方法
        proxy.writeBlog();
    }
}

運(yùn)行程序,控制臺(tái)打?。?/p>

start writing...
i'm writing...
end writing...

“Java代理模式是什么”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

分享名稱:Java代理模式是什么
標(biāo)題鏈接:http://bm7419.com/article44/gijoee.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗(yàn)、微信小程序、App開發(fā)、網(wǎng)站營(yíng)銷、靜態(tài)網(wǎng)站、定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)