zoukankan      html  css  js  c++  java
  • Java动态代理

    1. 特点:字节码随用随创建,随用随加载。(不同于装饰模式)

    2. 作用:不修改源码的基础上对方法增强

    3. 分类:

      1. 基于接口的动态代理
      2. 基于子类的动态代理
    4. 基于接口的动态代理:

      1. 涉及的类:Proxy;提供者:JDK官方
      2. 如何创建代理对象:使用Proxy类中的newProxyInstance方法
      3. 创建代理对象的要求:被代理类最少实现一个接口,如果没有则不能使用
      4. newProxyInstance方法的参数:
        1. ClassLoader :它是用于加载代理对象字节码的,和被代理对象使用相同的类加载器
        2. Class<?>[] :它是用于让代理对象和被代理对象有相同方法
        3. InvocationHandler :它是让我们写如何代理,我们一般都是写一个该接口的实现类,通常情况下都是使用匿名内部类,此接口的实现类都是谁用谁写。
      5. 最主要的是去实现InvocationHandler 中的invoke方法。
          public static void main(String[] args)
          {
              final Producer producer = new Producer();
      
              IProducer iProducer = (IProducer) Proxy.newProxyInstance(Producer.class.getClassLoader(), Producer.class.getInterfaces(), new InvocationHandler()
              {
                  /**
                   * 作用:执行被代理对象的任何接口方法都会经过该方法
                   * @param proxy     代理对象的引用
                   * @param method    当前执行的方法
                   * @param args      当前执行方法所需要的参数
                   * @return 和被代理对象方法有相同的返回值
                   * @throws Throwable
                   */
                  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
                  {
                      Object returnValue = null;
                      // 1.获取方法执行的参数
                      Float money = (Float) args[0];
                      // 2.判断当前方法是不是销售
                      if ("saleProduct".equals(method.getName()))
                      {
                          System.out.println("代理商获取0.2的利润");
                          returnValue = method.invoke(producer, money * 0.8f);
                      }
                      return returnValue;
                  }
              });
      
              iProducer.saleProduct(1000f);
          }
      
    5. 基于子类的动态代理

      1. 导入jar包:cglib
      2. 涉及的类:Enhancer,提供商:第三方cglib库
      3. 如何创建代理对象:使用Enhancer类中create方法
      4. 创建代理类的要求:被代理类不能是最终类
      5. create方法的参数:
        1. Class:它是用于加载代理对象字节码的,和被代理对象使用相同的类加载器
        2. Callback:它是让我们写如何代理,我们一般都是写一个该接口的实现类,通常情况下都是使用匿名内部类。我们一般写该接口的子接口实现类:MethodInterceptor
          public static void main(String[] args)
          {
              final Producer producer = new Producer();
      
              Producer proxyProducer = (Producer) Enhancer.create(producer.getClass(), new MethodInterceptor()
              {
                  /**
                   * 执行被代理对象方法都会经过该方法
                   * @param proxy
                   * @param method
                   * @param args
                   *      以上三个参数和基于接口实现动态代理一样
                   * @param methodProxy   当前执行方法的代理对象
                   * @return
                   * @throws Throwable
                   */
                  public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable
                  {
                      Object returnValue = null;
                      // 1.获取方法执行的参数
                      Float money = (Float) args[0];
                      // 2.判断当前方法是不是销售
                      if ("saleProduct".equals(method.getName()))
                      {
                          System.out.println("代理商获取0.2的利润");
                          returnValue = method.invoke(producer, money * 0.8f);
                      }
                      return returnValue;
                  }
              });
      
              proxyProducer.saleProduct(1000f);
          }
      
    ~~但愿绝望和无奈远走高飞~~
  • 相关阅读:
    [华为机试] 计算二进制数中1的个数
    vector释放
    opencv findcontours内存错误
    opencv的编译安装
    opencv SVM分类器模块的简单设计
    centos7.6安装FFMpeg
    centos安装jenkins
    centos 7.6安装Java
    Centos7 忘记密码的情况下,修改root或其他用户密码
    性能测试报告
  • 原文地址:https://www.cnblogs.com/jinchengll/p/11783337.html
Copyright © 2011-2022 走看看