设计模式之代理模式

代理模式

  1. 代理模式分为静态代理和动态代理.下图为静态代理结构图:

  1. 静态代理示例代码:

    // 抽象主题接口
    public interface Subject {
    
        void request();
    }
    
    // 具体主题角色
    public class RealSubject implements Subject{
        @Override
        public void request() {
            System.out.println("真实对象处理请求...");
            Random random = new Random();
            try {
                Thread.sleep(random.nextInt(1000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    // 代理角色
    public class Proxy implements Subject{
    
        private Subject subject;
    
        public Proxy(Subject subject) {
            this.subject = subject;
        }
    
        @Override
        public void request() {
            System.out.println("代理对象开始处理请求...");
            before();
            subject.request();
            after();
        }
    
        private void after() {
            System.out.println("proxy end...");
        }
    
        private void before() {
            System.out.println("proxy start...");
        }
    }
    // 测试
    public class ProxyTest {
    
        public static void main(String[] args) {
    
            Proxy proxy = new Proxy(new RealSubject());
            proxy.request();
        }
    }
    
    
  2. JDK动态代理示例代码:

    // 抽象接口
    public interface Person {
    
        void findWork();
    }
    
    // 具体对象
    public class Worker implements Person{
        @Override
        public void findWork() {
            System.out.println("打工人要找工作...");
        }
    }
    
    // 代理类,实现的是InvocationHandler接口
    public class JdkHr implements InvocationHandler {
    
        private Person target;
    
        public Person getInstance(Person person){
            this.target = person;
            Class<? extends Person> targetClass = target.getClass();
            return (Person) Proxy.newProxyInstance(targetClass.getClassLoader(), targetClass.getInterfaces(), this);
        }
    
        @Override
        public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
            before();
            Object invoke = method.invoke(this.target, objects);
            after();
            return invoke;
        }
    
        private void after() {
            System.out.println("proxy end...");
        }
    
        private void before() {
            System.out.println("proxy start...");
        }
    }
    
    // 测试
    public class JdkProxyTest {
    
        public static void main(String[] args) {
            // 这一行设置保存程序运行时的动态代理类class文件,方便查看
            System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true");
            JdkHr hr = new JdkHr();
            Person person = hr.getInstance(new Worker());
            person.findWork();
        }
    }
    
    
  3. CGLib动态代理示例代码:

      ```java
      // 抽象接口
      public interface Person {
      
          void findWork();
      }
      
      // 具体对象
      public class Worker implements Person{
          @Override
          public void findWork() {
              System.out.println("打工人要找工作...");
          }
      }
      
      // 代理类,实现的是MethodInterceptor接口
      public class CglibHr 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 {
              before();
              Object obj = methodProxy.invokeSuper(o, objects);
              after();
              return obj;
          }
      
          private void after() {
              System.out.println("proxy end...");
          }
      
          private void before() {
              System.out.println("proxy start...");
          }
      
      }
      
      // 测试
      public class CglibProxyTest {
      
          public static void main(String[] args) {
              // 这一行设置保存程序运行时的动态代理类class文件
              System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "cglibProxy/");
              CglibHr hr = new CglibHr();
              Person person = (Person) hr.getInstance(Worker.class);
              person.findWork();
          }
      }
      
      ```
    
  4. JDK和CGLib动态代理对比:

  1. 静态代理和动态代理对比:

  1. 总结:

    代理模式优点:将代理对象与真实被调用目标对象分离,降低了系统耦合性,扩展性好,并且可以增强目标对象的功能;

    代理模式缺点:系统中类的数量增加,导致处理请求的速度变慢,增加了系统的复杂度.

posted @ 2021-04-18 12:16  justKen  阅读(42)  评论(0编辑  收藏  举报