JDK动态代理学习

JDK动态代理,只能为接口创建动态代理
JDK的动态代理是通过java.lang.reflect.Proxy 和java.lang.reflect.InvocationHandler可以生成动态代理类或者代理对象
可以通过 java.lang.reflect.Proxy 来创建代理类或者代理实例:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
loader – 代理对象的类加载器,interfaces – 代理对象需要实现的接口,h 执行代理对象的每个方法时候会被替换执行h的invoke()方法。

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

public class ProxyTest {
    public static void main(String[] args) {
        Person person1= new PersonImpl();
        //创建一个InvocationHandler对象
        InvocationHandler in = new MyInvokationHandler(proxy);
        //使用指定的InvocationHandler来生成一个动态代理对象
        Person person = (Person)Proxy.newProxyInstance(proxy.getClass().getClassLoader(), new Class[]{Person.class}, in);
        //返回动态代理的实例
        Class<? extends InvocationHandler> aClass = Proxy.getInvocationHandler(person).getClass();
        System.out.println(aClass.getName());
        person.walk();
        person.sayHello("荀公达");

    }
}

interface Person {
    void walk();
    void sayHello(String name);
}
class PersonImpl implements Person  {

    @Override
    public void walk() {
        System.out.println(1);
    }

    @Override
    public void sayHello(String name) {
        System.out.println(2);
    }
}


class MyInvokationHandler implements InvocationHandler {
    private Object target;
    public MyInvokationHandler(Object target) {
        this.target = target;
    }
    /**
     *
     * @param proxy 代表动态代理对象
     * @param method 代表正在执行的方法
     * @param args 代表调用目标方法时传入的实参
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("-------------正在执行的方法:" + method);
        if (args != null) {
            System.out.println("下面是执行方法时传入的实参为");
            for (Object arg : args) {
                System.out.println(arg);
            }
        } else {
            System.out.println("调用该方法没有实参!");
        }
        return null;
    }
}

proxy:代表动态代理对象
method:代表正在执行的方法
args:代表调用目标方法时传入的实参
在执行上面程序时候,debug发现,proxy的参数的值不是被代理对象,而是null
在执行上面程序时候,debug发现,proxy的参数的值不是代理对象,而是nul
但是我在执行例子2时,proxy的值是被代理的对象

准备接口和接口的实现类

public interface Dog {
    void info();

    void run();
}
public class GunDog implements Dog {
    @Override
    public void info() {
        System.out.println("一只猎狗");
    }

    @Override
    public void run() {
        System.out.println("奔跑的速度");
    }
}

创建InvocationHandler的实现类

public class MyInvokationHandler implements InvocationHandler {
    //需要被代理的对象
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    //执行动态代理对象的所有方法时,都会被替换成执行如下的invoke方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        DogUtil dogUtil = new DogUtil();
        //执行dogutil中第一个method方法
        dogUtil.method();
        //已target作为主调来执行method方法
        Object result = method.invoke(target, args);
        //执行dogutil中第二个method2方法
        dogUtil.method2();
        return result;
    }
}

准备Proxy来生成动态代理类

public class MyProxyFactory {
    public static Object getProxy(Object target) {
        //创建一个MyInvokationHandler 对象
        MyInvokationHandler myInvokationHandler = new MyInvokationHandler();
        //为MyInvokationHandler设置target对象
        myInvokationHandler.setTarget(target);
        //创建并返回一个动态代理
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), myInvokationHandler);
    }
}

测试

public class Test {
    public static void main(String[] args) {
        Dog gunDog = new GunDog();
        Dog dog = (Dog)MyProxyFactory.getProxy(gunDog);
        dog.info();
        dog.run();
    }
}

运行以上代码发现proxy的值是我想要的值,就是被代理对象
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值