Java JDK动态代理详解

先说结论:

1、通过newProxyInstance创建真实的代理类,其第三个参数设置关联了实现InvocationHandler接口的类。
2、实现了InvocationHandler接口的类中提供invoke方法,供真实的代理类通过反射调用方法,并修改业务逻辑。

1、准备

创建接口---->

public interface people {
    void sayHello(String name);
    void working(String work);
}

创建接口的实现类—>

public class Student implements people{

    public void sayHello(String name) {
        System.out.println("Hello! "+name);
    }

    public void working(String work) {
        System.out.println("i'm "+work);
    }
}

创建继承了InvocationHandler对象的动态代理类---->
三个作用
1、初始化被代理类
2、创建真实代理类,与本类关联
3、真实代理类调用方法时,从invoke方法通过反射调用实际方法

public class JDKDynamicProxy implements InvocationHandler {
    //target为被代理的目标对象,作为构造方法的参数被初始化
    private Object target;

    public JDKDynamicProxy (Object target){
        this.target = target;
    }
    //使用Proxy的newProxyInstance方法,返回一个代理类对象
    @SuppressWarnings("Unchecked")
    public <T> T getProxy(){
        return (T) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),//生成该代理类对象的类加载器,用来加载代理类
                target.getClass().getInterfaces(),//获取实现类的interface对象数组,代理类对象可以调用接口中的方法
                this);                        //生成的动态代理对象调用方法时所关联到的InvocationHandler对象
    }
   // @Override 接口不能@Override
    //com.sun.proxy.$Proxy0对象在客户端调用方法时,调用newProxyInstance的第三个参数即实现InvocationHandler对象的invoke方法
    //invoke三个参数----JRE注入
    // proxy-->真实的代理对象  com.sun.proxy.$Proxy0
    //真实的代理对象不是this,this是JDK动态代理.JDKDynamicProxy
    //method-->所调用对象的方法的Method对象
    //args-->方法的参数
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println(proxy.getClass().getName());
        System.out.println(this.getClass().getName());
        before();
        Object result;
        if(method.getName().equals("sayHello")){
            System.out.println("调用了sayHello");
            //反射,方法的Method对象的invoke方法,输入方法的对象和方法参数,调用该方法
            result = method.invoke(target,args);
        }else {
            System.out.println("调用了work");
            result = method.invoke(target,args);
        }

        after();
        return result;
    }
    private void before(){
        System.out.println("before 动态代理");
    }
    private void after(){
        System.out.println("after 动态代理");
    }
}

2、客户端调用:
创建实现类的实例对象---->

 people peopleImp = new Student();//创建实现类

创建动态代理类的实例,把实现类对象作为参数,包装实现类---->

JDKDynamicProxy jdkDynamicProxy = new JDKDynamicProxy(peopleImp);

**

创建动态代理真实对象

**
啥是真实动态代理对象?
在代理类中invoke方法下写入

System.out.println(proxy.getClass().getName());
System.out.println(this.getClass().getName());

得到输出结果

com.sun.proxy.$Proxy0
JDK动态代理.Student

即:第一个输出结果是newProxyInstance方法创建的真实动态代理对象
第二个是实现了InvocationHandler接口的对象

注意第三个参数,即生成的真实动态代理对象调用方法时所关联到的InvocationHandler对象

people peopleProxy = (people) Proxy.newProxyInstance(
peopleImp.getClass().getClassLoader(),
peopleImp.getClass().getInterfaces(),
jdkDynamicProxy);

动态代理真实对象(com.sun.proxy.$Proxy0)调用其使用newProxyInstance方法创建时的第三个参数,即实现了InvocationHandler接口的对象(JDK动态代理.Student)的invoke方法,通过反射实现方法调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值