java动态代理基础

本文详细介绍了Java动态代理的实现过程,包括使用cglib和JDK方式创建代理,以及如何通过InvocationHandler拦截并记录方法执行耗时。重点展示了如何为接口创建代理实例和测试类的使用。
摘要由CSDN通过智能技术生成

动态代理实现步骤

java动态代理是一种在运行时创建接口代理对象的机制,它允许你在不修改原有代码的情况下,对方法调用进行拦截和处理。

1. 定义接口:首先,你需要定义一个或多个接口,这些接口将被动态代理类实现。这些接口定义了代理对象应该具备的行为。
2. 实现InvocationHandler接口:这个接口中只有一个方法invoke,它负责处理所有代理方法的调用。(可采用匿名内部类的方式书写)
3. 创建代理实例:使用Proxy类的newProxyInstance静态方法来创建代理实例
类加载器(ClassLoader):用于加载代理类和接口的类加载器。
接口数组(Class<?>[] interfaces):代理类实现的接口数组(需要代理哪些)
调用处理器(InvocationHandler):实现了InvocationHandler接口的实例,负责处理所有方法调用。
4. 使用代理对象

动态代理实现计算方法执行耗时

定义代理接口,

动态代理只能为接口创建代理实例

public interface ProxyInte {
     void from1ToN(int n) throws InterruptedException;
     void NTo1(int n) throws InterruptedException;
    public void  sort(int []arr);
}

定义代理类,实现接口,重写方法:

public class TestProxy implements ProxyInte{
    @Override
    public void from1ToN(int n) throws InterruptedException {
        for (int i = 0; i < n; i++) {
            Thread.sleep(1);
        }
    }
    @Override
    public void NTo1(int n) throws InterruptedException {
        while (n>=1){
            n--;
            Thread.sleep(2);
        }
    }
    @Override
    public void  sort(int []arr){
        Arrays.sort(arr);
    }
}

创建代理:

    /**
     * 创建一个动态代理对象,该代理对象将计算方法执行的耗时。
     *
     * @param target 被代理的对象,它实现了TestProxy接口
     * @return 返回一个实现了ProxyInte接口的代理对象
     */
    public static ProxyInte createProxy(TestProxy target) {
        // 使用Proxy.newProxyInstance方法创建代理对象
        ProxyInte proxy = (ProxyInte) Proxy.newProxyInstance(
                TestProxy.class.getClassLoader(), // 使用TestProxy接口的类加载器
                target.getClass().getInterfaces(), // 获取目标对象实现的所有接口new Class[]{ProxyInte.class},这里我只有一个接口
                new InvocationHandler() {
                    /**
                     * 实现InvocationHandler接口的invoke方法,该方法将拦截所有代理对象的方法调用。
                     *
                     * @param proxy 代理对象本身,通常不使用
                     * @param method 被调用的方法对象
                     * @param args 被调用方法的参数数组
                     * @return 返回方法调用的结果
                     * @throws Throwable 如果方法调用抛出异常,则这里也会抛出
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        long start = System.currentTimeMillis(); // 记录方法开始执行的时间
                        Object result = method.invoke(target, args); // 调用目标对象的方法
                        long end = System.currentTimeMillis(); // 记录方法结束执行的时间
                        // 打印方法名和执行耗时
                        System.out.println(method.getName() + "执行耗时" + (end - start) + "ms");
                        return result; // 返回方法调用的结果
                    }
                }
        );
        return proxy; // 返回创建的代理对象
    }
}

创建测试类运行(使用):

public class test {
    public static void main(String[] args) throws InterruptedException {
        ProxyInte p = MyProxy.createProxy(new TestProxy());

        p.from1ToN(100);
        p.NTo1(120);

        Random r = new Random();
        int[] arr = new int[5000];
        for (int i = 0; i < arr.length; i++) {
            arr[i]=r.nextInt(0,1000);
        }
        p.sort(arr);
    }
}

在这里插入图片描述

cglib代理

通过父子继承关系来创建代理:
代理类是子类型
目标方法是父类类型(方法和类不能为final关键字修饰)

Enhancer.create(
父类型,
Callback
)

JDK代理

newProxyInstance(

)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值