java 动态代理(详细图解)

动态代理

就是对象的执行方法,由代理proxy来负责,就比如user.get()方法,是由User对象亲自去执行,而使用代理就是由proxy去执行

  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的,不是我们直接写的
  • 动态代理分类两大类:基于接口的动态代理和基于类的动态代理

基于接口 JDK原生动态代理 基于类:cglib java字节码的动态代理

动态代理具体例子:
在这里插入图片描述
参考网站:
https://www.liaoxuefeng.com/wiki/1252599548343744/1264804593397984
https://blog.csdn.net/yaomingyang/article/details/80981004
https://zhuanlan.zhihu.com/p/42516717

接口,有两个对象

public interface Ihello{
    void sayHello(String name);
    void sayGoodBye(String name);
}

实现接口类

public  class Helloimplements implements IHello{
    @Override
    public void sayHello(String name){
        System.out.println("Hello"+name);
    }
    @Override
    public void sayGoodBye(String name){
        System.out.println(name+"GoodBye");
    }
}

现在是多了一个需求,要求在实现类每次问候的时候,把问候的细节记录到日志中,也就是在修改成,在问候前答应一句
System.out.println(“问候之前的日志记录…”)

方法一:
直接在impl实现类上改

public  class Helloimplements implements IHello{
    @Override
    public void sayHello(String name){
        System.out.println("问候之前的日志记录...")
        System.out.println("Hello"+name);
    }
    @Override
    public void sayGoodBye(String name){
        System.out.println(name+"GoodBye");
    }
}

可是基本是不允许修改原来的Helloimplements类

方法二:
设计模式中的代理模式:

创建一个Java类作为代理类,实现hello接口,并且把impl的实例 通过一个set方法给传递到代理类中,在代理类上面增加新的功能

完整代码:

public class StaticProxy implements IHello{
    //这里有一个新的类
    private IHello iHello;
    public void setImpl(IHello impl){
        this.iHello=impl;
    }
    
      @Override
    public void sayHello(String name){
        System.out.println("问候之前的日志记录...")
        iHello.sayHello(name);
    }
    @Override
    public void sayGoodBye(String name){
        iHello.sayGoodBye(name);
    }
    
    public void static main(String[] arg){
        Helloimplements hello=new Helloimplements();
        StaticProxy proxy=new StaticProxy();
        //然后把对应实例引入
        proxy.setImpl(hello);
        proxy.sayHello("Jerry")
    }
    
}

方法三:动态代理的invocationHandler
其中InvocationHandler(接口)和Proxy(类)是最重要的

invocationHandler接口是proxy代理实例的调用处理程序的一个接口,每一个proxy代理实例都有一个关联的调用处理程序,在代理实例调用方法时,方法调用就会被编码分配到
invcationHandler的invoke方法中

Proxy类就是用来创建一个代理对象的类,其中的newProxyInstance就是最常见的方法

简单来说就是:

  1. 定义一个InvocationHandler实例,用来实现方法的调用
  2. 通过Proxy.newProxyInstance()创建实例,其中有三个参数(classloader,接口,用来处理接口方法调用的 invocationHandler(很可能是this))
  3. 将返回的object强制转型为接口

其中还有一个容易混淆的概念:
method.invoke

method.invoke(Object obj,Object args[])的作用就是调用method类代表的方法,其中obj是对象名,args是传入method方法的参数
主要是这个invoke中的参数代表什么,好像是 先知道这个方法是什么,然后就是方法里的参数吧
就像 方法是:

public int intShow (int num) {
return num;
}

然后先通过反射获得方法:
Method method=clazz.getMathod(“intShow”,int.class)
//为什么后面这个是int.class 是因为本来也是返回的是class类型的

再进行调用
int num=(int)method.invoke(new InvokeObj(),89)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值