java动态代理

23 天前(已编辑)
20

java动态代理

什么是动态代理?

java的动态代理是一种在运行时动态创建代理对象的机制,主要用于在不修改原始类的情况下对方法调用进行拦截和增强。
动态代理是一种方便运行时动态构建代理、动态处理代理方法调用的机制,很多场景都是利用类似机制做到的,比如用来包装 RPC 调用、面向切面的编程(AOP)。

关于动态代理的一些问题

1.为什么需要代理?

代理可以无侵入式的给对象增强其他的功能

2.代理长什么样?

代理里面就是对象要被代理的方法

3.java通过什么来保证代理的样子?

通过接口来保证,后面的对象和代理需要实现同一个接口,接口中就是被代理的所有方法。

代码例子

说白了,动态代理就是用于功能增强,且避免了侵入式的修改

  • 情景:来自黑马的鸡哥与经济公司

    截图2025-12-26 221059

    截图2025-12-26 221059

    接口Star

    public interface Star {
      public  abstract String sing(String name);
      public abstract void dance (String  name);
    }

    实现类BigStar

    public class BigStar implements Star{
      private String name;
      public BigStar() {
      }
       public BigStar(String name) {
          this.name = name;
      }
      //唱歌 跳舞
      @Override
      public String sing(String name){
          System.out.println(name+"正在唱歌");
          return "谢谢";
      }
      @Override
      public void dance(String name){
          System.out.println(name+"正在跳舞");
      }
      /**
       * 获取
       * @return name
       */
      public String getName() {
          return name;
      }
      /**
       * 设置
       * @param name
       */
      public void setName(String name) {
          this.name = name;
      }
    
      public String toString() {
          return "BigStar{name = " + name + "}";
      }
    }

代理类

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

public class ProUtil {
    //public static Object newProxyInstance(ClassLoader loder, Class<?> interface, InvocationHandler h)
    /*
     *参数一:用于指定用哪个类加载器。去加载生成的代理类
     *参数二:指定接口,这些接口用于指定生成的代理长什么样,也就是有哪些方法
     *参数三:用来指定生成的代理对象要干什么事
     */
    public static Star createProxy(BigStar bigStar){
        Star star = (Star) Proxy.newProxyInstance(
                ProUtil.class.getClassLoader(),
                new Class[] {Star.class},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        /**
                         * proxy:代理对象
                         * method:正在调用的方法
                         * args:调用方法时传入的参数
                         */
                        if (method.getName().equals("sing")) {
                            System.out.println("开始代理,准备话筒");
                        }
                        if (method.getName().equals("dance")) {
                            System.out.println("开始代理,准备场地");
                        }
                        return method.invoke(bigStar, args);
                    }
                }
                );
        return star;
    }
}

运行结果

截图2025-12-26 220946

截图2025-12-26 220946

为什么非要用代理而不是直接调用

来自d指导

与直接调用相比,使用动态代理有以下几个重要原因:
●1. 解耦业务逻辑与横切关注点:在企业应用中,像日志记录、事务管理、权限验证等功能会跨越多个业务模块,这些被称为横切关注点。动态代理允许将这些通用功能与核心业务逻辑分离,避免代码冗余。例如在你提供的代码中,ClientProxy类通过动态代理将远程方法调用的逻辑(如构建请求、与服务端通信等)与具体的业务逻辑分离,使得业务代码更专注于核心功能。
● 2.非侵入式增强:动态代理可以在不修改目标对象代码的前提下,对其功能进行增强,这符合开闭原则。比如你要为现有系统中的多个服务添加日志记录功能,如果直接调用,就需要在每个服务的方法中添加日志代码,这会修改大量的原有代码。而使用动态代理,只需在InvocationHandler的invoke方法中添加日志记录逻辑,就可以为所有代理的服务添加日志功能,无需修改目标服务的代码。
●3. 实现 AOP 编程:动态代理是 AOP(面向切面编程)的核心实现机制。通过动态代理,可以在方法调用前后插入特定的逻辑,如在方法调用前进行权限校验,在方法调用后进行事务提交等。在你的代码中,ClientProxy类的invoke方法就可以看作是一个切面,它在代理对象的方法调用前后执行了构建请求、发送请求和处理响应等逻辑。

AOP 全称 Aspect-Oriented Programming(面向切面编程),核心思想是 将与业务无关、但被多个业务模块共享的逻辑(比如日志、事务、RPC 通信)抽取出来,形成独立的 "切面",在不修改>业务代码的前提下,动态织入到目标方法的调用流程中。

● 4.提高代码的灵活性和可维护性:动态代理在运行时生成代理对象,相比静态代理更加灵活。它可以根据条件动态选择代理策略,支持在运行时配置不同的增强逻辑。例如,在不同的环境下,可以选择不同的序列化方式或传输协议来发送请求,而这些只需要在invoke方法中进行简单的条件判断和配置即可,无需修改大量的代码。同时,由于增强逻辑集中在InvocationHandler中,所以当需要修改或扩展增强逻辑时,只需要在一个地方进行修改,便于维护。

使用社交账号登录

  • Loading...
  • Loading...
  • Loading...
  • Loading...
  • Loading...