jdk动态代理实现原理总结

Posted cai-cai777

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdk动态代理实现原理总结相关的知识,希望对你有一定的参考价值。

运行时创建一个代理对象的步骤为

  1. 生成代理类的字节码
  2. 加载字节码,创建代理对象

首先,代理对象的目的是在被调用方法的时候既能实现被代理对象的方法,又能够增加自己想要执行的方法,自然要获得被代理对象

代理类需要实现被代理对象的类的接口,因此生成的代理对象可以调用被代理对象所执行的方法。因此,创建代理类需要获得被代理对象的类的接口(反射获得)

代理类实现的接口方法由用户自定义放到一个类方法里,因此代理类需要拿到这个用户自定义的类(构造方法或者set方法)

既然要加载字节码,肯定要获得classLoader,可以由被代理对象从反射获得。

 

因此生成代理对象的方法为

//target为代理对象

public <T> T getProxy() 
        return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),//类加载器,用于加载生成的代理类字节码
    target.getClass().getInterfaces(), //代理类需要实现被代理对象的类的接口
     this//用户自定义的代理方法的实现
);
以上为下面完整实现代码的截取 完整动态代理实现例子如下:
摘自

JDK动态代理实现原理

package com.lnjecit.proxy;

/**
 * Subject
 * 抽象主题接口
 * @author
 * @create 2018-03-29 14:16
 **/
public interface Subject 

    void doSomething();
技术图片

 

 然后为接口RealSubject新建一个实现类RealSubject

技术图片
/**
 * RealSubject
 * 真实主题类
 * @author
 * @create 2018-03-29 14:21
 **/
public class RealSubject implements Subject 
    @Override
    public void doSomething() 
        System.out.println("RealSubject do something");
    
技术图片

 

 接着创建一个代理类JDKDynamicProxy实现java.lang.reflect.InvocationHandler接口,重写invoke方法

 

技术图片
package com.lnjecit.proxy.dynamic.jdk;

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

/**
 * JDKDynamicProxy
 * jdkd动态代理
 *
 * @author
 * @create 2018-03-29 16:17
 **/
public class JDKDynamicProxy implements InvocationHandler 

    private Object target;

    public JDKDynamicProxy(Object target) 
        this.target = target;
    

    /**
     * 获取被代理接口实例对象
     * @param <T>
     * @return
     */
    public <T> T getProxy() 
        return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
        System.out.println("Do something before");
        Object result = method.invoke(target, args);
        System.out.println("Do something after");
        return result;
    
技术图片

 

新建测试类Client测试结果

 

技术图片
package com.lnjecit.proxy;

import com.lnjecit.proxy.dynamic.jdk.JDKDynamicProxy;

/**
 * Client
 * client测试代码
 *
 * @author
 * @create 2018-03-29 14:26
 **/
public class Client 
    public static void main(String[] args) 
        // 保存生成的代理类的字节码文件
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

        // jdk动态代理测试
        Subject subject = new JDKDynamicProxy(new RealSubject()).getProxy();
        subject.doSomething();
    
技术图片

 

输出结果:

Do something before
RealSubject do something
Do something after

 

以上是关于jdk动态代理实现原理总结的主要内容,如果未能解决你的问题,请参考以下文章

JDK 动态代理(原理 + 代码实现)

细说JDK动态代理的实现原理

jdk动态代理和cglib动态代理底层实现原理超详细解析(jdk动态代理篇)

JDK动态代理的底层实现原理

JDK动态代理的底层实现原理

JDK和CGLIB动态代理原理