JAVA动态代理实现(一)

本文介绍了使用JDK自带反射机制实现动态代理的具体方法,并提供了一个通用的动态代理类实现示例,包括创建代理对象和调用目标方法的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


目前,本人知道的动态代理实现方式有两种,一种是通过JDK自带的反射机制实现,另一种是第三方动态代理框架CGLIB。这两种方式,JDK实现的话获取代理对象会比CGLIB快,但是在使用代理对象,进行方法调用的时候,CGLIB却比JDK的快(性能高)!!


现在先介绍,JDK自带的反射机制包如何实现动态代理,本人已经写成通用的类


被代理类接口 ISayHello.java:

package dynamicproxy.jdk;

/**
 * 文件名称: ISayHello.java
 * 编写人: yh.zeng
 * 编写时间: 17-1-18 下午6:14
 * 文件描述: todo
 */
public interface ISayHello
{
    public void sayHello();

}

两个被代理的类SayHelloImpl.java 和 SayHelloImpl2.java,这里写两个只是为了测试本人写的代理类实现是否是通用的

SayHelloImpl.java

package dynamicproxy.jdk;

/**
 * 文件名称: SayHelloImpl.java
 * 编写人: yh.zeng
 * 编写时间: 17-1-18 下午6:15
 * 文件描述: todo
 */
public class SayHelloImpl implements ISayHello
{
    private String word = null;

    @Override
    public void sayHello() {
        System.out.println("Hello World!");
    }

}

SayHelloImpl2.java

package dynamicproxy.jdk;

/**
 * 文件名称: SayHelloImp2.java
 * 编写人: yh.zeng
 * 编写时间: 17-1-18 下午7:19
 * 文件描述: todo
 */
public class SayHelloImp2  implements ISayHello
{
    private  String word = null;

    public  SayHelloImp2(String word){
        this.word = word;
    }

    @Override
    public void sayHello() {
        System.out.println(word);
    }
}


动态代理实现类 JdkDynamicProxyHandler.java:


package dynamicproxy.jdk;

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

/**
 * 文件名称: JdkDynamicProxyHandler.java
 * 编写人: yh.zeng
 * 编写时间: 17-1-18 下午6:25
 * 文件描述: 动态代理工具类,通过JDK自带的反射机制包实现
 */
public class JdkDynamicProxyHandler implements InvocationHandler
{
    private Object realObj = null;        //被代理的对象,自动生成
    private Class realClass = null;       //被代理的类,作为参数传入构造方法
    private Object[] realObjArgs = null;  //被代理的类的构造方法的参数,作为参数传入构造方法
    private Object proxyObj = null;       //代理对象,自动生成

    /**
     *
     * @param realClass    被代理的类
     */
    public JdkDynamicProxyHandler(Class realClass){
        this.realClass = realClass;
    }


    /**
     *
     * @param realClass   被代理的类
     * @param args     被代理的类的构造方法的参数
     */
    public JdkDynamicProxyHandler(Class realClass, Object... args){
        this.realClass = realClass;
        this.realObjArgs = args;
    }

    /**
     * 获取代理对象
     * @return  Object
     */
    public synchronized Object getProxyObj(){
        if(proxyObj == null){
            this.proxyObj =  Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), realClass.getInterfaces(), this);
        }
        return proxyObj;
    }

    /**
     * 最终调用被代理的对象的方法的实现代码
     * @param proxy
     * @param method
     * @param args
     * @return 返回被代理对象调用相应方法返回的值
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(realObj == null){
            Constructor constructor = null;
            if(realObjArgs != null && realObjArgs.length > 0){ //调用被代理类的有参构造方法进行实例化
                Class clazz[] = new Class[realObjArgs.length];
                for(int i = 0; i < clazz.length; i++){
                    clazz[i] = realObjArgs[i].getClass();
                }
                constructor = realClass.getConstructor(clazz);
                realObj = constructor.newInstance(realObjArgs);
            }else{    //调用被代理类的无参构造方法进行实例化
                constructor = realClass.getConstructor();
                realObj = constructor.newInstance();
            }

        }
        return method.invoke(realObj, args);
    }
}


测试demo:

package dynamicproxy.jdk;

import java.lang.reflect.Proxy;

/**
 * 文件名称: JdkDynamicProxyTest.java
 * 编写人: yh.zeng
 * 编写时间: 17-1-18 下午6:24
 * 文件描述: todo
 */
public class JdkDynamicProxyTest
{

    public static void main(String args[]) {
        //无构造参数demo
        ISayHello sayHello = (ISayHello)  new JdkDynamicProxyHandler(SayHelloImpl.class).getProxyObj();
        sayHello.sayHello();

        //有构造参数的demo
        ISayHello sayHello2 = (ISayHello)  new JdkDynamicProxyHandler(SayHelloImp2.class,new Object[]{"Hello World2!"}).getProxyObj();
        sayHello2.sayHello();
    }

}


运行结果:


Hello World!
Hello World2!

Process finished with exit code 0



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值