美文网首页
保护代理

保护代理

作者: 码了个寂寞 | 来源:发表于2021-05-12 14:04 被阅读0次

保护代理的实现方式有两种:静态代理和动态代理。首先代理模式的作用是什么呢?控制访问。

代理模式

  • 场景
    为其他对象提供一种代理,控制对这个对象的访问——控制访问

  • 条件(特点)
    1、代理对象和被代理对象继承同一个父类
    2、代理对象持有被代理对象的引用

  • 为什么要满足这个条件
    当然是做控制访问,代理类和被代理类继承或实现同一个接口,实际操作的还是被代理类,代理类只是做访问控制

虚代理

  • 根据需要创建开销很大的对象,该对象只有在需要的时候才会被真正创建
  • 懒加载 LazyLoad,ORM(对象映射关系框架)

静态代理

首先引用一个案例:

代理模式条件首先是代理对象和被代理对象要继承或实现同一个接口,所以先定义一个接口 OrderApi

  public interface OrderApi {

    public String getUserName();

    public void setUserName(String userName,String updateUser);

    public String getOrderName();

    public void setOrderName(String orderName,String updateUser);

    public String getOrderId();

    public void setOrderId(String orderId,String updateUser);

    public String getOrderTime();

    public void setOrderTime(String orderTime,String updateUser);

}

然后定义一个被代理类Order(实际做业务操作的类,以下以JavaBean做示范,并非说被代理类是JavaBean),然后实现OrderAPI接口

public class Order implements OrderApi {

    private String userName;
    private String orderName;
    private String orderId;
    private String orderTime;
    

    public Order(String userName, String orderName, String orderId, String orderTime) {
        super();
        this.userName = userName;
        this.orderName = orderName;
        this.orderId = orderId;
        this.orderTime = orderTime;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName,String updateUser) {
        this.userName = userName;
    }

    public String getOrderName() {
        return orderName;
    }

    public void setOrderName(String orderName,String updateUser) {
        this.orderName = orderName;
    }

    public String getOrderId() {
        return orderId;
    }

    public void setOrderId(String orderId,String updateUser) {
        this.orderId = orderId;
    }

    public String getOrderTime() {
        return orderTime;
    }

    public void setOrderTime(String orderTime,String updateUser) {
        this.orderTime = orderTime;
    }

}

然后定义一个代理类OrderProxy,实现OrderApi接口并持有Order被代理类引用,当进行set操作的时候做权限判断,只有本人可以修改这个订单:

public class OrderProxy implements OrderApi {

    private Order order;

    public OrderProxy(Order order) {
        this.order = order;
    }

    @Override
    public String getUserName() {
        return order.getUserName();
    }

    @Override
    public void setUserName(String userName, String updateUser) {
        if (updateUser != null && updateUser.equals(order.getUserName())) {
            order.setUserName(userName, updateUser);
        } else {
            throw new IllegalAccessError(updateUser + "同学,你没有权限操作!");
        }
    }

    @Override
    public String getOrderName() {
        return order.getOrderName();
    }

    @Override
    public void setOrderName(String orderName, String updateUser) {
        if (updateUser != null && updateUser.equals(order.getUserName())) {
            order.setOrderName(orderName, updateUser);
        } else {
            throw new IllegalAccessError(updateUser + "同学,你没有权限操作!");
        }
    }

    @Override
    public String getOrderId() {
        return order.getOrderId();
    }

    @Override
    public void setOrderId(String orderId, String updateUser) {
        if (updateUser != null && updateUser.equals(order.getUserName())) {
            order.setOrderId(orderId, updateUser);
        } else {
            throw new IllegalAccessError(updateUser + "同学,你没有权限操作!");
        }
    }

    @Override
    public String getOrderTime() {
        return order.getOrderTime();
    }

    @Override
    public void setOrderTime(String orderTime, String updateUser) {
        if (updateUser != null && updateUser.equals(order.getUserName())) {
            order.setOrderTime(orderTime, updateUser);
        } else {
            throw new IllegalAccessError(updateUser + "同学,你没有权限操作!");
        }
    }

}

最后写一个测试类:

public class Client {
    
    public static void main(String[] args) {
        
        Order order = new Order("张三","Mac Pro 订单","999999","2021/03/12");

        OrderProxy orderProxy = new OrderProxy(order);
        
        orderProxy.setOrderName("iPhone 12 Pro Max 订单", "张三");
        
        System.out.println("现在的订单名称为:"+orderProxy.getOrderName());
        
    }
    
}

通过以上的一个案例会发现静态代理有一个很大的确定,那就是做权限 保护判断等逻辑的时候,代理类里的每个函数都需要手动判断一次,特别繁琐导致一堆垃圾代码,而且如果目标接口发生改变,被代理类对应的函数也需要改一遍很麻烦,这时候就引入了一个动态代理:

动态代理

  • 不需要手动创建代理对象,而是由JVM自动帮我们创建,而且代理对象自动实现了目标接口
  • 他是通过动态生成class字节码做到的


    image.png

具体是怎么做的呢?


image.png

自动生成的代理类对应的每个函数会做这样一个操作,将当前函数传入到InvocationHandler实现类的invoke函数中,再在InvocationHandler 的 invoke函数中做统一权限等判断操作最后调用被代理类对应的函数

public class DynamicInvocationHandler implements InvocationHandler {

    private Order order;

    public void setTarget(Order order) {
        this.order = order;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 所有被代理对象的方法被执行,都会传入到invoke方法中
        // 方法名称只要是set开头,进行权限检查
        if (method.getName().startsWith("set")) {
            if (order != null && order.getUserName() != null && order.getUserName().equals(args[1])) {
                return method.invoke(order, args);
            } else {
                throw new IllegalAccessError("没有操作权限!");
            }
        }
        return method.invoke(order, args);
    }

}

相关文章

  • 保护代理

    保护代理的实现方式有两种:静态代理和动态代理。首先代理模式的作用是什么呢?控制访问。 代理模式 场景为其他对象提供...

  • JavaScript 设计模式(中)——3.代理模式

    3 代理模式 代理模式:为一个对象提供一个代用品或占位符,以便控制对它的访问。代理模式分为保护代理和虚拟代理,保护...

  • JavaScript设计模式--代理模式

    一、定义 代理模式:为一个对象提供一个代用品或占位符,以便控制对它的访问。代理分为:保护代理和虚拟代理保护代理:用...

  • 代理模式

    代理模式(proxy):为其他对象提供一种代理以控制对这个对象的访问。 代理种类:保护代理、动态代理【iOS没有】...

  • 设计模式

    1.代理模式 定义:为其他对象提供一种代理,以控制对这个对象的访问。 远程代理 虚拟代理 保护代理 智能引用代理静...

  • 保护代理模式

    输出结果

  • 设计模式(十五)代理模式-控制对象访问

    分类 代理有很多实现: 远程代理,控制访问远程对象 虚拟代理,控制访问创建开销大的资源 保护代理,基于权限控制对资...

  • 代理模式

    代理模式的典型就是springAOP代理模式的目的有两个:保护目标对象,增强目标对象分类:静态代理和动态代理。 静...

  • 设计模式-之-代理模式和面向接口编程

    一、代理模式简介 代理设计模式优点:(1) 保护真实对象(2) 让真实对象职责更明确.(3) 扩展 代理设计模式(...

  • 设计模式——代理模式

    1、代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问。2、保护代理和虚拟代理1)代理 B 可以帮助 ...

网友评论

      本文标题:保护代理

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