美文网首页
代理模式

代理模式

作者: Lucksheep | 来源:发表于2019-05-15 15:58 被阅读0次

一、代理模式的简介

  1. 代理模式:为其他对象提供一种代理以控制对这个对象的访问;
  2. 归类:创建型模式
  3. 目的:拿到目标类的引用,能够调用业务类的方法;

二、代理模式的必须具备的条件

  1. 必须要两个角色:执行者、被代理人;
  2. 被代理人必须有一件要做的事情但是没有时间做亦或者不想做;
  3. 对于代理人来说,必须要获取被代理人的个人信息。

三、静态代理和动态代理的区别

  1. 静态代理类返回值必须是具体的类(在代理之前,所有的东西都是已知的)–不方便扩展
  2. 动态代理类返回值可以不是具体的类(在代理之前,所有的东西都是未知的)–方便扩展

四、静态代理的实现

  1. 定义要做的事情接口:Person.java

package com.demo.proxy.statics;
/**
 * 用户找房子
 */
public interface Person {
    public void findHome();
}

  1. 被代理类:XiaoFeiYang.java

package com.demo.proxy.statics;
/**
 * 被代理人:小肥羊
 * 要做的事情:找房子
 * 要求:找一个3室一厅、坐北朝南、带阳台的房子
 */
public class XiaoFeiYang implements Person {
    @Override
    public void findHome() {
        //工作太多了,产品突然加了10价格需求,没有时间找房子
        System.out.println("找一个3室一厅、坐北朝南、带阳台的房子");
    }
}

  1. 代理类:Intermediary.java

package com.demo.proxy.statics;
/**
 * 代理人:中介
 */
public class Intermediary {
    private Person person;
    public Intermediary(Person person){
        this.person = person;
    }
    //目标对象的引用给拿到
    public void findHome(){
        System.out.println("根据你的要求找房中..........");
        this.person.findHome();
        System.out.println("找到了:这个房子刚好满足你的条件");
    }
}

  1. 测试:StaticProxyTest.java

package com.demo.proxy.statics;
public class StaticProxyTest {
    public static void main(String[] args) {
        //中介帮小肥羊找房
        Intermediary intermediary = new Intermediary(new XiaoFeiYang());
        intermediary.findHome();
        //实现出来了,但是发现木有,代理类(Intermediary)真心不能扩展了哦
    }
}

  1. 测试结果:

根据你的要求找房中..........
找一个3室一厅、坐北朝南、带阳台的房子
找到了:这个房子刚好满足你的条件

五、jdk动态代理的实现

  1. 接口:Person2.java

package com.demo.proxy.jdk;
public interface Person2 {
    public void findHome();
    public void findGirlFriend();
}

  1. 被代理对象:XiaoFeiYang2.java

package com.demo.proxy.jdk;
/**
 * 被代理人:小肥羊
 */
public class XiaoFeiYang2 implements Person2{
    @Override
    public void findHome() {
        System.out.println("找一个3室一厅、坐北朝南、带阳台的房子");
    }
    @Override
    public void findGirlFriend() {
        System.out.println("找女朋友,身材S型,皮肤白里透红,身高170CM,出的厅堂下得厨房,晚上还能暖床,善解人意,有自己的性格和想法");
    }
}

  1. 代理:Intermediary2.java

package com.demo.proxy.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * 代理人:三方代理
 */
public class Intermediary2 implements InvocationHandler {
    //持有被代理人的引用
    private Person2 person2;
    public Object getInstance(Person2 person2) throws Exception{
        this.person2=person2;
        Class<?> clazz=person2.getClass();
        //生成一个新的对象(实际就是字节码重组)
        return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("我是三方代理:我要给你找对象,现在已经拿到你的需求");
        System.out.println("寻找中..........");
        method.invoke(this.person2,args);
        System.out.println("如果合适的话,就准备办喜事吧,emmmmmmmm");
        return null;
    }
}

  1. 测试类:JDKProxyTest.java

package com.demo.proxy.jdk;
import sun.misc.ProxyGenerator;
import java.io.FileOutputStream;
/**
 * Created by Tom on 2018/3/10.
 */
public class JDKProxyTest {
    public static void main(String[] args) {
        try {
            Person2 obj = (Person2)new Intermediary2().getInstance(new XiaoFeiYang2());
            System.out.println(obj.getClass());
            obj.findGirlFriend();
            //在这里,我们可以看到 输出里面有个 class com.sun.proxy.$Proxy0,来我们反编译下,看看是什么东西
            byte[] bytes=ProxyGenerator.generateProxyClass("$Proxy0",new Class[]{Person2.class});
            //输出文件到E盘
            FileOutputStream os = new FileOutputStream("F://$Proxy0.class");
            os.write(bytes);
            os.close();
            //通过反编译文件
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

六、cglib动态代理的实现

被代理类


package com.demo.proxy.cglib;
/**
 * 被代理人:小肥羊
 * 要做的事情:找房子
 * 要求:找一个3室一厅、坐北朝南、带阳台的房子
 */
public class XiaoFeiYang2 {
    public void findHome() {
        //工作太多了,产品突然加了10价格需求,没有时间找房子
        System.out.println("找一个3室一厅、坐北朝南、带阳台的房子");
    }
}

代理类:


package com.demo.proxy.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
 * 代理人:中介
 */
public class Intermediary2 implements MethodInterceptor {
    public Object getInstance(Class<?> clazz){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return  enhancer.create();
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //这里我是不是可以给任何人代理做事情?
        //比如我给人当媒婆,给人代驾等等。。。
        System.out.println("我是中介哦:我要给你找房子");
        System.out.println("现在已经拿到你的需求");
        methodProxy.invokeSuper(o,objects);
        System.out.println("开始找...........");
        System.out.println("找到合适的,准备付钱吧");
        return null;
    }
}

测试类:


package com.demo.proxy.cglib;
public class Test {
    public static void main(String[] args) {
        XiaoFeiYang2 obj = (XiaoFeiYang2)new Intermediary2().getInstance(XiaoFeiYang2.class);
        obj.findHome();
    }
}

相关文章

  • 设计模式

    单例模式 模板方法模式 工厂模式 代理模式 静态代理 JDK动态代理

  • 设计模式

    单例模式 代理模式 静态代理 jdk动态代理 cglib动态代理 工厂模式 适配器模式 建造者模式 观察者模式

  • kube-proxy的3种模式

    userspace代理模式 iptables代理模式 IPVS代理模式 https://kubernetes.io...

  • 第4章 结构型模式-代理模式

    一、代理模式简介 二、代理模式3个角色 三、代理模式的优点 四、代理模式的实例(游戏代练)

  • 理解代理模式

    原创博客地址 简介 代理模式,也叫做委托模式,分为:静态代理动态代理 代理模式也是平时比较常用的设计模式之一,代理...

  • 结构型 代理模式(文末有项目连接)

    1:什么是代理模式 2:没用代理模式时的实例 3:使用代理模式将其解耦(静态代理) 3:使用代理模式将其解耦(动态...

  • 设计模式-动态代理模式

    之前介绍了代理模式,大家也都了解了代理模式,不过之前介绍的代理模式是静态代理,静态代理什么意思?静态代理指的是代理...

  • 代理模式

    一、什么是代理模式 代理模式(Proxy pattern):代理模式又叫委托模式,是为某个对象提供一个代理对象,并...

  • 设计模式之代理模式(Proxy模式)

    代理模式的引入 代理模式的实例程序 代理模式的分析 代理模式的引入 Proxy是代理人的意思,指的是代替别人进行工...

  • Java设计模式之代理模式

    Java设计模式之代理模式 代理模式 静态代理 动态代理 为什么需要代理 通过代理,我们能够不用知道委托人是谁,而...

网友评论

      本文标题:代理模式

      本文链接:https://www.haomeiwen.com/subject/ivapaqtx.html