zoukankan      html  css  js  c++  java
  • 代理模式

    代理模式

    1.定义

    • 代理模式,为其他对象提供一种代理以控制对这个对象的访问。
    • 代理对象在客户端和目标对象之间起到中介作用。属于结构型设计模式。
    package cn.sun.code.seven;
    
    /**
     * Subject类,定义了RealSubject和Proxy的公共接口,这样就在任何使用RealSubject的地方都可以
     * 使用Proxy
     */
    interface Subject {
    
    	void request();
    
    }
    
    /**
     * RealSubject类,定义Proxy所代表的真实实体
     */
    class RealSubject implements Subject {
    
    	@Override
    	public void request() {
    		System.out.println("真实的请求");
    	}
    }
    
    /**
     * Proxy类,保存一个引用使得代理可以访问实体,并提供一个与Subject的接口相同的接口
     * 这样代理就可以用来代替实体
     */
    public class Proxy implements Subject {
    
    	private RealSubject realSubject;
    
    	@Override
    	public void request() {
    		// 可以在这里给被代理对象定制一些特性
    		if (realSubject == null) {
    			realSubject = new RealSubject();
    		}
    		System.out.println("对委托类开始增强");
    		realSubject.request();
    		System.out.println("对委托类增强结束");
    	}
    
    }
    
    /**
     * 客户端代码
     */
    class Client {
    
    	public static void main(String[] args) {
    		Proxy proxy = new Proxy();
    		proxy.request();
    	}
    
    }
    

    2.为什么使用代理模式

    • 代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能。

    3.静态代理

    • 静态代理在使用时,需要定义接口或者父类,被代理对象与与代理对象一起实现相同的接口或者是继承相同父类。

      • 定义中的示例即为标准静态代理方式。
      • 关键,在编译期确定代理对象,在程序运行前代理类的.class文件就已经存在。
    • 静态代理的缺陷:

      • 每个代理类都必须实现一遍委托类(realSubject)的接口,如果接口增加方法,则代理类也必须跟着修改。增加了代码维护的复杂度。

    4.动态代理

    • 动态代理是根据代理的对象,动态创建代理类。
    • 动态代理是通过反射实现的,可以借助Java自带的java.lang.reflect.Proxy实现
      1. 编写一个委托类的接口,即静态代理中的Subject接口
      2. 实现一个委托类,即静态代理中的RealSubject类
      3. 创建一个动态代理类,实现InvocationHandler接口,并重写该invoke()方法
      4. 在客户端中,生成动态代理对象
    package cn.sun.code.seven;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * 动态代理类
     */
    public class DynamicProxy implements InvocationHandler {
    
    	private Object object;
    
    	public DynamicProxy(Object object) {
    		this.object = object;
    	}
    
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		System.out.println("对委托类开始增强");
    		Object invoke = method.invoke(object, args);
    		System.out.println("对委托类增强结束");
    		return invoke;
    	}
    
    }
    
    /**
     * 客户端对象
     */
    class Client2 {
    
    	public static void main(String[] args) {
    		Subject realSubject = new RealSubject();
    		DynamicProxy proxy = new DynamicProxy(realSubject);
    		ClassLoader classLoader = realSubject.getClass().getClassLoader();
    		Subject subject = (Subject) Proxy.newProxyInstance(classLoader, new Class[]{Subject.class}, proxy);
    		subject.request();
    	}
    }
    
    
    • InvocationHandler接口说明

        /**
         * {@code InvocationHandler} is the interface implemented by
         * the <i>invocation handler</i> of a proxy instance.
         *
         * <p>Each proxy instance has an associated invocation handler.
         * When a method is invoked on a proxy instance, the method
         * invocation is encoded and dispatched to the {@code invoke}
         * method of its invocation handler.
         *
         */
      
      • 每一个动态代理类都必须要实现InvocationHandler这个接口,并且每个代理类的实例都关联到了一个handler,当我们通过代理对象调用一个方法的时候,这个方法的调用就会被转发为由InvocationHandler这个接口的 invoke 方法来进行调用。

      • invoke()方法

        •     public Object invoke(Object proxy, Method method, Object[] args)
                  throws Throwable;
          // proxy:指我们所代理的那个真实对象
          // method:指我们所要调用真实对象的某个方法的method对象
          // args:指调用真实方法某个对象时所接受的参数
          

    • Proxy类说明

      • Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods. 
        
      • Proxy这个类的作用就是用来动态创建一个代理对象的类,它提供了许多静态方法,但是我们用的最多的就是newProxyInstance()这个方法:

        • public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,  InvocationHandler h)  throws IllegalArgumentException
          
          • loader:一个ClassLoader对象,定义由哪个ClassLoader对象来对生成的代理对象进行加载
          • interfaces:一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口,这样生成的代理类就能调用这组接口中的方法了
          • h:一个InvocationHandler对象,表示的是当这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
  • 相关阅读:
    c# 基本值类型及其默认值
    军史馆如何营造更好的意境
    部队营区生态环境设计与文化氛围营造
    我的第一个CAD程序
    经典SQL语句大全
    带图标和多行显示的ListBox
    CAD 二次开发 -- 自动加载开发的DLL
    Git使用总结
    OpenStack迁移虚拟机流程分析
    OpenStack创建虚拟机流程
  • 原文地址:https://www.cnblogs.com/riders/p/12660783.html
Copyright © 2011-2022 走看看