Java基础学习(十九)

Java基础学习(十九):动态代理

本文为个人学习记录,内容学习自 黑马程序员


概念

  • 作用:可以无侵入式地给代码增加额外的功能
  • 代理内部就是对象要被代理的方法
  • 实际步骤:调用者先调用代理中的方法,实现一些额外的功能,再由代理去调用对象中的方法
图19-1

使用

  • 路径:java.lang.reflect.Proxy

  • 创建代理

    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
    参数一:用于指定用哪个类加载器,去加载生成的代理类
    参数二:指定接口,这些接口用于指定生成的代理长什么样,也就是有哪些方法
    参数三:用来指定生成的代理对象要干什么事情
    
  • 代码实现:

    1. 需要被代理的类:

      // 需要实现接口Star,在接口中指定了需要被代理的方法
      public class BigStar implements Star {
          private String name;
      
          public BigStar() {
          }
      
          public BigStar(String name) {
              this.name = name;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          @Override
          public String toString() {
              return "BigStar{" +
                      "name='" + name + '\'' +
                      '}';
          }
      
          @Override
          public void sing(String name) {
              System.out.println(this.name + "正在唱" + name);
          }
      
          @Override
          public void dance() {
              System.out.println(this.name + "正在跳");
          }
      }
      
    2. 接口:

      // 在接口中指定要代理的方法
      public interface Star {
          public abstract void sing(String name);
          public abstract void dance();
      }
      
    3. 代理工具类:

      public class ProxyUtil {
          // 方法的作用:给定一个需要被代理的对象,创建一个代理
          // 形参:需要被代理的对象
          // 返回值:创建的代理,由于代理需要实现接口,因此可以直接用接口类型作为返回值类型(多态)
          public static Star createProxy(BigStar bigStar) {
              Star star = (Star) Proxy.newProxyInstance(
                  	// 参数一:用于指定用哪个类加载器,去加载生成的代理类
      				// 参数二:指定接口,这些接口用于指定生成的代理长什么样,也就是有哪些方法
      				// 参数三:用来指定生成的代理对象要干什么事情
                      ProxyUtil.class.getClassLoader(),
                      new Class[]{Star.class},
                      new InvocationHandler() {
                          @Override
                          // 参数一:代理的对象
                          // 参数二:要运行的方法
                          // 参数三:调用方法时传递的实参
                          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                              // 进行准备工作(额外的功能)
                              if ("sing".equals(method.getName())) {
                                  System.out.println("唱歌准备工作");
                              } else if ("dance".equals(method.getName())) {
                                  System.out.println("跳舞准备工作");
                              }
                              // 调用被代理者的方法(原来的功能)——利用反射
                              Object result = method.invoke(bigStar, args);
                              return result;
                          }
                      }
              );
              return star;
          }
      }
      
    4. 测试类:

      public class Test {
          public static void main(String[] args) {
              BigStar bigStar = new BigStar("明星小a");
              Star proxy = ProxyUtil.createProxy(bigStar);
      
              proxy.sing("歌曲b");
              proxy.dance();
          }
      }
      
posted @   victoria6013  阅读(3)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示