java中的動態(tài)代理(一)

一、動態(tài)代理的作用

    1. 什么是代理

代理模式的意圖是通過提供一個代理( Proxy )或者占位符來控制對該對象的訪問。

    1. 使用的場景

在我們生活中,代理也是隨處可見,其中中介就是一個很好的例子,把代理看做生活中的中介,將更加易于理解,試想一下,如果我們想租房或者買房的話通過中間是不是就可以讓我們非常省心。

二、靜態(tài)代理

在java中又兩種代理模型,稱之為靜態(tài)代理和動態(tài)代理。為了保證與所代理的對象功能行為的一致性,代理類一般需要實現(xiàn)實體類所實現(xiàn)的同一個接口,以下即為一個最基本的代理模式的結構。

首先提供一個接口供實體類和代理類實現(xiàn)。

/**
 * Created by jiangcheng on 2017/11/19.
 *
 * 抽象接口
 */
public interface Subject {
    // 統(tǒng)一行為
    void doSomeThing();
}

實體類:

public class RealSubject implements Subject {

    @Override
    public void doSomeThing() {
        System.out.println(" RealSubject do somethings ");
    }
}

代理類:

public class SubjectProxy implements Subject {

    private RealSubject mRealSubject;

    public SubjectProxy(RealSubject realSubject) {
        mRealSubject = realSubject;
    }

    @Override
    public void doSomeThing() {
        // 這里就是所謂的aop 面向切面編程了, 你可以在調用實際功能之前或者之后做一些額外的處理
        System.out.println(" RealSubject do somethings  before");
        mRealSubject.doSomeThing();
        System.out.println(" RealSubject do somethings  after");
    }
}

測試類:


public class TestProxy {

    public static void main(String args[]) {
        Subject sub = new SubjectProxy(new RealSubject());
        sub.doSomeThing();
    }
}

結果:


靜態(tài)代理結果.png

從上面的例子可以看到調用的時候我們對實體類做了一層封裝,從代碼角度看,反而實現(xiàn)上更加復雜了,沒有體現(xiàn)出代理模式的優(yōu)勢,其實代理模式的作用就是通過代理對象控制實體對象的訪問,從而提高訪問的安全性,而且可以在調用實體類的方法時做一些預處理和善后的工作,就是所謂的aop(面向切面編程)。這樣就保證了實體類可以拋開復雜的業(yè)務邏輯而只去實現(xiàn)一些最純粹的功能,提高了代碼的可讀性和靈活性。

三、動態(tài)代理

這個才是今天的重點,我們可以想一下,萬一實現(xiàn)Subject接口的實體類不止一個呢,是不是需要創(chuàng)建SubjectProxy1、SubjectProxy2...這樣的,那么這樣就不是很靈活了呢,動態(tài)代理就能實現(xiàn)。
今天我們介紹JDK的動態(tài)代理,其實還有一種動態(tài)代理cglib,在web開發(fā)中用的比較多,所以就不展開講述了,JDK中已經為我們提提供好了動態(tài)代理接口 InvocationHandler 我們只需要實現(xiàn)它即可創(chuàng)建一個動態(tài)代理類。如下:

/**
 * Created by jiangcheng on 2017/11/19.
 * 動態(tài)代理
 */

public class DynamicProxy implements InvocationHandler {

    private Object mObject;

    public DynamicProxy(Object object) {
        mObject = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(" DynamicProxy is called");
        return method.invoke(mObject, args);
    }

    /**
     * 對外提供一個創(chuàng)建動態(tài)代理對象的方法
     * @param object
     * @return
     */
    public static Object newProxyInstance(Object object) {
        return Proxy.newProxyInstance(object.getClass().getClassLoader(),
                object.getClass().getInterfaces(), new DynamicProxy(object));
    }
}

調用:

    public static void main(String args[]) {
//        Subject sub = new SubjectProxy(new RealSubject());
//        sub.doSomeThing();

        // 這里利用的是強轉(動態(tài)創(chuàng)建),所以當有RealSubject2、RealSubject3對象需要代理時,只需要創(chuàng)建一個代理類就行了
        Subject subject = (Subject) DynamicProxy.newProxyInstance(new RealSubject());
        subject.doSomeThing();
    }

結果:


動態(tài)代理結果.png

好了,靜態(tài)代理和動態(tài)代理的基本使用和例子都寫完了,但是InvocationHandler的invoke方法是由誰來調用的,代理對象是怎么生成的。invoke()方法中的一些參數(shù)的是什么呢,這就得等到下一part來講述了。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 原文: Dyanmic Proxy Classes 介紹 一個動態(tài)代理類是實現(xiàn)了多個接口存在于運行時的類,這樣,一...
    半黑月缺閱讀 1,094評論 0 0
  • 從三月份找實習到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,787評論 11 349
  • Java代理和動態(tài)代理機制分析和應用 概述 代理是一種常用的設計模式,其目的就是為其他對象提供一個代理以控制對某個...
    丸_子閱讀 3,159評論 6 57
  • 1、處理內存不足的接口:didReceiveMemoryWarning //處理內存不足的接口:內存不足時,調用到...
    小番茄加西紅柿閱讀 546評論 0 0
  • 搜索引擎遇到的挑戰(zhàn): 1.頁面抓取需要快而全面 2.海量數(shù)據(jù)存儲 3.索引處理快速有效,具可擴展性 4.查詢處理快...
    古月hans閱讀 414評論 0 0

友情鏈接更多精彩內容