美文网首页
代理模式

代理模式

作者: 古早味蛋糕 | 来源:发表于2022-12-03 20:07 被阅读0次
1、简介

1.1 代理是一个中间者的角色
它屏蔽了访问方和委托方之间的直接接触。也就是说访问方不能直接调用委托方的这个对象,而是必须实例化一个跟委托方有同样接口的代理方,通过这个代理方来完成对委托方的调用。访问方只和代理方打交道,这个代理方有点像掮客的角色,现实生活中的代理类似于中介机构。

1.2 什么时候需要用到代理模式呢?

  • 访问方不想和委托方有直接接触,或者直接接触有困难。
  • 访问方对委托方的访问需要增加额外的处理,例如访问前和访问后都做一些处理。这种情况下我们不能直接对委托方的方法进行修改,因为这样会违反“开闭原则”。

1.3 代理模式有两类:静态代理和动态代理,下面我们通过代码分别详细说明。

2、静态代理

静态代理的代理类每次都需要手动创建。

public interface Icar {
    void move();
}
public class Benz implements Icar{
    @Override
    public void move() {
        System.out.println("Benz move ...");
    }
}
/**
 * 静态代理
 */
public class BenzProxy implements Icar{
    private Benz benz;

    public BenzProxy() {
        benz = new Benz();
    }

    @Override
    public void move() {
        //做一些前置工作 例如:检查车子的状况
        System.out.println("检查车子的状况。。。");
        benz.move();
        //做一些后置工作 例如检查结果
        System.out.println("车子2020-10-21号出厂,空调坏了。");

    }
}

最后调用

public class ProxyMain {
    public static void main(String[] args) {
        BenzProxy benzProxy = new BenzProxy();
        benzProxy.move();
    }
}
3、 动态代理

动态代理的代理类可以根据委托类自动生成,而不需要像静态代理那样通过手动创建。动态代理类的代码不是在Java代码中定义的,而是在运行的时候动态生成的。这里主要用到InvocationHandler接口。

//动态代理类
public class CarHandler implements InvocationHandler {
    //目标类的引用
    private Object target;

    public CarHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object object, Method method, Object[] args) throws Throwable {
        //做一些前置工作 例如:检查车子的状况
        before();
        Object result = method.invoke(target, args);
        //做一些后置工作 例如检查结果
        after();
        return result;
    }
    private void before() {
        System.out.println("检查车子的状况。。。");
    }
    private void after() {
        System.out.println("车子2019-10-1号出厂,空调坏了。");
    }
}

调用动态代理:

public static void main(String[] args) {
    ICar iCar = new Benz();
    InvocationHandler handler = new CarHandler(iCar);
    ICar proxy = (ICar) Proxy.newProxyInstance(ICar.class.getClassLoader(), new Class[]{ICar.class}, handler);
    proxy.move();
}
4、 动态代理应用:简单工厂

接着上面动态代理调用方的使用方式,通过工厂模式加上泛型的方式,优化一下动态代理的生成和调用。

public class ProxyFactory <T>{
    private T client;//目标对象
    private IBefore before;
    private IAfter after;

    public <T> T createProxy(){
        ClassLoader loader = client.getClass().getClassLoader();
        Class<?>[] interfaces = client.getClass().getInterfaces();
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                if ("getName".equals(method.getName())){
                    //可根据name值过滤方法
                }
                //前置
                if (before != null){
                    before.doBefore();
                }
                //执行目标对象的方法
                Object result = method.invoke(client, objects);
                //后置
                if (after != null){
                    after.doAfter();
                }
                return result;
            }
        };
        return (T) Proxy.newProxyInstance(loader,interfaces,handler);
    }

    public void setClient(T client) {
        this.client = client;
    }

    public void setBefore(IBefore before) {
        this.before = before;
    }

    public void setAfter(IAfter after) {
        this.after = after;
    }
}

创建前后置接口

public interface IAfter {
    void doAfter();
}
public interface IBefore {
    void doBefore();
}

使用和具体的产品业务分离出来了,方便维护和拓展:

public static void main(String[] args) {
    //创建工厂
    ProxyFactory factory = new ProxyFactory();

    factory.setBefore(new IBefore() {
        @Override
        public void doBefore() {
            System.out.println(" doBefore...");
        }
    });
    factory.setClient(new Benz());

    factory.setAfter(new IAfter() {
        @Override
        public void doAfter() {
            System.out.println(" doAfter...");
        }
    });
    //创建代理
    ICar iCar = (ICar) factory.createProxy();
    iCar.move();
}
5、 动态代理应用:AOP

AOP的英文全称是Aspect-Oriented Programming,即面向切面编程。AOP的实现方式之一是动态代理。
简单来说,AOP能够动态地将代码切入指定的位置,在指定位置上实现编程,从而达到动态改变原有代码的目的。
上面的IBefore和IAfter接口实际上就是简单地实现了AOP,例如在invoke具体方法之前和之后插入一些操作。
另外Proxy.newProxyInstance这个方法:

  public static Object newProxyInstance(ClassLoader 
    loader,Class<?>[] interfaces,InvocationHandler h)
  • loader:委托类的classLoader。
  • interfaces:代理类需要实现的接口,这个接口同委托类的接口。
  • h:调用处理器,只有一个invoke方法,调用委托类的任何方法都是通过它的invoke方法来完成的。

相关文章

  • 设计模式

    单例模式 模板方法模式 工厂模式 代理模式 静态代理 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/gkmufdtx.html