動態(tài)代理

Java 中的動態(tài)代理

源碼分析實(shí)現(xiàn)原理的過程

http://blog.csdn.net/bluetjs/article/details/52263410

步驟

  1. 必須要有一個(gè)接口, Subject

  2. 有一個(gè)類實(shí)現(xiàn)接口,RealSubject

  3. 實(shí)現(xiàn) InvocationHandler 接口,書寫代理類的邏輯

  4. 通過 Proxy.newProxyInstance 方法創(chuàng)建代理對象

代碼:

package com.interview.reflect;

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

public class ProxyTest {

    public static void main(String[] args) {
        Subject s = new RealSubject();
        Subject subject = (Subject) Proxy.newProxyInstance(s.getClass().getClassLoader(),
        s.getClass().getInterfaces(), new ProxyHandler<Subject>(s));
        subject.method();
        subject.dream();

    }
}

interface Subject {

    void method();

    void dream();

}

class RealSubject implements Subject {

    @Override
    public void method() {
        System.out.println("method run...");
    }

    @Override
    public void dream() {
        System.out.println("dream come true...");
    }
}

class ProxyHandler<T> implements InvocationHandler {

    private T target;

    public ProxyHandler(T target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before invoke method process<<<<");
        method.invoke(target, args);
        System.out.println("after method invoke process>>>>>>");
        return target;
    }
}

運(yùn)行結(jié)果

before invoke method process
method run...
after method invoke process
before invoke method process
dream come true...
after method invoke process

底層實(shí)現(xiàn)

JDK提供了sun.misc.ProxyGenerator.generateProxyClass(String proxyName,class[] interfaces) 底層方法來產(chǎn)生動態(tài)代理類的字節(jié)碼,這是 proxy 的底層實(shí)現(xiàn)

仔細(xì)觀察可以看出生成的動態(tài)代理類有以下特點(diǎn):

  1. 繼承自 java.lang.reflect.Proxy,實(shí)現(xiàn)了目標(biāo)類需要實(shí)現(xiàn)的接口

  2. 類中的所有方法都是 final 的

  3. 所有的方法功能的實(shí)現(xiàn)都統(tǒng)一調(diào)用了 InvocationHandler 的 invoke() 方法

cglib 的動態(tài)代理

Java 的動態(tài)代理的缺點(diǎn)是類必須要實(shí)現(xiàn)接口,如果沒有實(shí)現(xiàn)接口則無法產(chǎn)生代理。為了應(yīng)對這種情況,于是就產(chǎn)生了 cglib 的動態(tài)代理。

cglib 創(chuàng)建某個(gè)類A的動態(tài)代理類的模式是

  1. 查找A上的所有非final 的public類型的方法定義

  2. 將這些方法的定義轉(zhuǎn)換成字節(jié)碼

  3. 將組成的字節(jié)碼轉(zhuǎn)換成相應(yīng)的代理的class對象

  4. 實(shí)現(xiàn) MethodInterceptor接口,用來處理 對代理類上所有方法的請求(這個(gè)接口和JDK動態(tài)代理InvocationHandler的功能和角色是一樣的)

其他的字節(jié)碼工具

javaassist,asm

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

相關(guān)閱讀更多精彩內(nèi)容

  • title: Jdk動態(tài)代理原理解析 tags:代理 categories:筆記 date: 2017-06-14...
    行徑行閱讀 19,625評論 3 36
  • Java代理和動態(tài)代理機(jī)制分析和應(yīng)用 概述 代理是一種常用的設(shè)計(jì)模式,其目的就是為其他對象提供一個(gè)代理以控制對某個(gè)...
    丸_子閱讀 3,164評論 6 57
  • 一、代理的概念與作用 1.1、生活中的代理 杭州人從在杭州本地從杭州的代理商(線下商店)中買聯(lián)想電腦和直接跑到北京...
    俠客有情劍無情QAQ閱讀 8,482評論 3 13
  • 01 在行為心理學(xué)中,一個(gè)人的新的習(xí)慣或者理念的形成并得以鞏固至少需要21天。 而我用21天養(yǎng)成了早起寫作的習(xí)慣。...
    星飛飛閱讀 2,387評論 98 136
  • 2015年對我來說絕對是非常重要的一年,結(jié)婚生子,完成了人生中非常重要的幾件大事。 閨女的出生完全出乎我的意料,在...
    程沐閱讀 629評論 8 6

友情鏈接更多精彩內(nèi)容