JDK动态代理模式

本文介绍了JDK动态代理的原理和实现方式,强调了必须有接口这一前提条件。核心是InvocationHandler接口和Proxy类,InvocationHandler的invoke方法在调用代理对象的方法时执行预处理和后置处理逻辑。Proxy类的newProxyInstance方法用于生成代理对象。通过示例展示了如何创建和使用JDK代理,包括目标接口、目标类和代理类的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        JDK动态代理的前提是必须有接口,JDK 动态代理会为每个业务接口动态生成相应的代理类实现,并加载到 JVM 中,然后创建对应的代理实例对象。

        JDK 动态代理的实现原理:动态创建代理类,然后通过指定类加载器进行加载。

        

     1)  JDK动态代理的核心是InvocationHandler接口,该接口只包含一个抽象方法      

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;

 参数说明:

        Object proxy — 被代理的对象

        Method method — 被代理的方法

        Object[] args — 被代理方法的参数数组

2)Proxy类

该类包含代理相关的静态方法,最常用的是生成代理对象

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

参数说明:

        loader(ClassLoader 类型):加载动态生成的代理类的类加载器。

        interfaces(Class[] 类型):业务类实现的接口。

        h(InvocationHandler 类型):自定义的 InvocationHandler 对象。

        

该方法的功能如下:

        1).生成一个实现了参数interfaces里所有接口且继承了Proxy的代理类的字节码,然后用参数里的classLoader加载这个代理类。

        2).使用代理类父类的构造函数 Proxy(InvocationHandler h)来创造一个代理类的实例,将我们自定义的InvocationHandler的子类传入。

        3).返回这个代理类实例。

示例:

目标接口

public interface Subject {
    void sayHello();
}

目标类:

public class RealSubject implements Subject{

    @Override
    public void sayHello() {
        System.out.println("hello, I am RealSubject");
    }
}

用于生成JDK代理的类

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

public class JDKProxy implements InvocationHandler {

  private Object target; // 真正的业务对象,需要代理的目标对象

  // DemoInvokerHandler构造方法
  public JDKProxy(Object target) {
    this.target = target;
  }

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    System.out.println("before do...");   // 在执行业务逻辑之前的预处理逻辑

    Object result = method.invoke(target, args);

    System.out.println("after do...");   // 在执行业务逻辑之后的后置处理逻辑
    return result;
  }

  public Object getProxy() {  //获取代理对象
    // 创建代理对象
    return Proxy.newProxyInstance(Thread.currentThread()
                        .getContextClassLoader(),
                        target.getClass().getInterfaces(), this);
  }

}

测试

public class Test {
    public static void main(String[] args) {
        Subject subjectProxy = (Subject)new JDKProxy(new RealSubject()).getProxy();
        subjectProxy.sayHello();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值