(JAVA)-动态代理

发布时间:2024年01月04日

代理在我们生活中很常见:

:当我们想看演唱会时,让黄牛帮我们排队买。

:当明星要唱歌时,委托别人帮忙准备。

:老婆想吃饭,让老公帮他做饭。

代理模式就是把我们不愿意做的事情委托给别的对象做。

静态代理:我们以吃饭为例子写个demo说明

假设老婆该干的事情有:1.做饭2.吃饭

老婆将做饭工作交给老公(代理)来做

1.首先得定义一个接口,把要代理的方法放进去,老公和老婆都实现了这个接口

public interface things {//把想要代理的方法放进来
void eat();
}

2.接着我们来定义老婆的类:老婆会吃饭。


public class wife implements things 

    public wife() {
    }

  private String name;

    public wife(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void eat(){
        System.out.println(this.name+"正在吃饭");
    }
}

3.定义老公的类老公帮老婆做饭

package staticProxy;

public class husband implements things {
    private String name;
    private wife w;

    public husband(String name, wife w) {
        this.name = name;
        this.w = w;
    }

    public husband(wife w) {
        this.w=w;
    }


    @Override
    public void eat() {
        this.cook();
        w.eat();
    }
    public void cook(){
        System.out.println(this.name+"把饭做好了");
    }
}

最后来调用main方法创建老公老婆对象。

public class test {
    public static void main(String[] args) {
        wife w1=new wife("xuxu");
        husband h1=new husband("dengdeng",w1);
        h1.eat();
    }
}

我们可以看到老婆把做饭的任务交给了老公执行。

动态代理:当我们的狗狗也想吃饭了怎么办呢?我们可以通过动态代理的方式解决

我们可以通过Proxy这个类中的静态方法newProxyInstance来获取一个动态代理。

    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)

?newProxyInstance方法的返回值是创建的代理对象。newProxyInstance方法有三个形参:

第一个形参代表着加载类的加载器,通过获取到加载器让他把代理加载到内存中。常常是一个固定格式。

第二个形参是要代理方法的字节码的字节码数组。

第三个形参是一个接口,里面的invoke方法是代理的方法的实现。代理使用方法后会自动调用。

invoke方法参数一:代理的对象,参数二,代理的方法,参数三,调用sing方法传递的实参,返回值:方法运行返回值

package staticProxy;

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

public class ProxyUtil {
    //给wife创建一个做饭的代理
    public static things createProxy(Object w){
       things t= (things)Proxy.newProxyInstance(
               ProxyUtil.class.getClassLoader(),//加载类的加载器,让他把当前的代理加载到内存当中
               new Class[]{things.class},//实现接口的字节码
               new InvocationHandler() {//代理方法实现
                   @Override
                   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                      //参数一:代理的对象,参数二,代理的方法,参数三,调用sing方法传递的实参,返回值:方法运行返回值
                       System.out.println("代理把饭做好了");
                      return method.invoke(w,args);
                   }
               }
       );
       return t;
    }
}

注意:将传入对象设置成object类型这样就能接收任意类型的对象

  things t1 = ProxyUtil.createProxy(w1);
        t1.eat();
        dog d1=new dog("欢欢");
        things t2 = ProxyUtil.createProxy(d1);
t2.eat();

由结果可知,代理不仅帮了诩诩做饭,还帮了狗做饭。

注意:我们并不是所有的方法都需要这个代理去做饭。我们知道只有诩诩和狗去看吃饭时,才需要代理,如果要实现我们想要的方法上面添加特定的代理,可以通过 invoke 方法里面的方法反射获取 method 对象方法名称即可实现。

在吃饭语句前加上判断。

                 if("eat".equals(method.getName()))

文章来源:https://blog.csdn.net/fdvvg/article/details/135386580
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。