java设计模式代理模式

  • 静态代理

    主要有三个角色:抽象角色,代理类,被代理类。

  1. 抽象角色:封装了代理类和被代理类的共有的特性,通过此接口来实现代理类和被代理类的外观上的一致。
    public abstract class Subject {
        public abstract void request();
    }
  2. 代理类:实现代理的类,当客户端需要访问被代理类时,通过代理类类完成,因此此类中应包含一个被代理类的引用,已实现对被代理类的调用。在完成对被代理对象的调用的同时还可加入自己的操作。
    public class ProxySubject extends Subject {

        private RealSubject realSubject;
        public void request() {
            if(null == realSubject){
                realSubject = new RealSubject();
            }

            pre();
            realSubject.request();
            post();

        }

        private static void pre(){
            System.out.println("before");
        }

        private static void post(){
            System.out.println("after");
        }

    }

  3. 被代理类:实际实现操作的类,被代理类来调用实现功能。
    public class RealSubject extends Subject {

        public void request() {

            System.out.println("real subject");
        }

    }
  4. 测试类
    public class TestStaticProxy {

        public static void main(String[] args) {
            Subject subject = new ProxySubject();

            subject.request();
        }
    }
    静态代理是在编译期间已经实现了代理类对被代理的代理操作。
  • 动态代理抽象角色必须为接口:

    public interface Subject {

             public void request();
           }
   动态代理类:

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

/**
 * 代理类
 * @author Administrator
 *
 */
public class DynamicProxy implements InvocationHandler {

    //被代理对象的引用
    public Object sub;
    
    //在构造方法中初始化被代理对象
    public DynamicProxy(Object obj){
        this.sub = obj;
    }

    //第一个参数生成的代理类,第二个参数封装好的方法对象,第三个参数方法的参数
    //
    //返回值与被调用方法的返回值类型相同
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("before calling method:" + method);
        
        System.out.println(proxy.getClass());
        //调用绑定到被代理对象上的相应的方法
        Object object = method.invoke(sub, args);
        
        System.out.println("after calling method:" + method);
        
        return object;
    }
}

被代理类与静态代理中相同

测试类:


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

public class TestDynamic01 {

    public static void main(String[] args) {
        
        //将需要被代理的对象new RealSubject()传递给代理对象,
        //则代理对象拥有了被代理对象的引用
        InvocationHandler dProxy = new DynamicProxy(new RealSubject());
        
        //使用Proxy类的静态方法newProxyInstance()来生成一个动态的代理类
        //当然在生成这个动态代理对象时需要三个参数:
        //1.代理对象的类加载器来加载代理类到jvm,可以使用代理类或被代理类的classLoader
        //2.被代理类的实现的接口对象class
        //3.代理类对象的实例,用来调用方法的一个处理器即调用代理类的invoke方法
        //返回一个根据上面参数动态生成的代理对象
        Subject sub = (Subject)Proxy.newProxyInstance(RealSubject.class.getClassLoader(),
                RealSubject.class.getInterfaces(), dProxy);
        //调用动态生成的对象中的方法,根据dProxy对象来运用反射来实现相应方法调用
        sub.request();
        
        System.out.println(sub.getClass());
    }
    
}

原文地址:https://www.cnblogs.com/charleszhang1988/p/3051971.html