JDK 动态代理的五大使用步骤(附代码实例)

参考答案

JDK 动态代理的五大使用步骤

  1. 通过实现 InvocationHandler 接口,来自定义自己的 InvocationHandler ;
  2. 通过 Proxy.getProxyClass,获得动态代理类;
  3. 通过反射机制,获得代理类的构造方法,方法签名为getConstructor(InvocationHandler.class)
  4. 通过构造函数,获得代理对象,并将自定义的InvocationHandler实例对象传为参数传入;
  5. 通过代理对象,调用目标方法。

JDK 动态代理的五大使用步骤的代码实例

public interface IHello {
    void sayHello();
}
 public class HelloImpl implements IHello {
    @Override
    public void sayHello() {
        System.out.println("Hello world!");
    }
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
 
public class MyInvocationHandler implements InvocationHandler {
 
    /** 目标对象 */
    private Object target;
 
    public MyInvocationHandler(Object target){
        this.target = target;
    }
 
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("------插入前置通知代码-------------");
        // 执行相应的目标方法
        Object rs = method.invoke(target,args);
        System.out.println("------插入后置处理代码-------------");
        return rs;
    }
}
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;

public class MyProxyTest {
    public static void main(String[] args)
            throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        // =========================第一种==========================
        // 1、生成$Proxy0的class文件
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        // 2、获取动态代理类
        Class proxyClazz = Proxy.getProxyClass(IHello.class.getClassLoader(),IHello.class);
        // 3、获得代理类的构造函数,并传入参数类型InvocationHandler.class
        Constructor constructor = proxyClazz.getConstructor(InvocationHandler.class);
        // 4、通过构造函数来创建动态代理对象,将自定义的InvocationHandler实例传入
        IHello iHello1 = (IHello) constructor.newInstance(new MyInvocationHandler(new HelloImpl()));
        // 5、通过代理对象调用目标方法
        iHello1.sayHello();
 
        // ==========================第二种=============================
        /**
         * Proxy类中还有个将2~4步骤封装好的简便方法来创建动态代理对象,
         *其方法签名为:newProxyInstance(ClassLoader loader,Class<?>[] instance, InvocationHandler h)
         */
        IHello  iHello2 = (IHello) Proxy.newProxyInstance(IHello.class.getClassLoader(), // 加载接口的类加载器
                new Class[]{IHello.class}, // 一组接口
                new MyInvocationHandler(new HelloImpl())); // 自定义的InvocationHandler
        iHello2.sayHello();
    }
}

JDK 静态代理与 JDK 动态代理的相同与不同之处。

相同之处:

  • 都要创建代理类;
  • 代理类都要实现接口;
  • …等等

不同之处:

  • 在静态代理中,我们需要对哪个接口和哪个被代理类创建代理类,因此在编译前,代理类需要实现与被代理类相同的接口,同时直接在实现的方法中,调用被代理类相应的方法;
  • 动态代理是在运行时被创建的,我们不知道要针对哪个接口,哪个被代理类创建代理类。

以上,是Java面试题【JDK动态代理的五大使用步骤】的参考答案。

输出,是最好的学习方法

欢迎在评论区留下你的问题、笔记或知识点补充~

—end—

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧