参考答案
JDK 动态代理的五大使用步骤
-
通过实现 InvocationHandler 接口,来自定义自己的 InvocationHandler ; -
通过 Proxy.getProxyClass
,获得动态代理类; -
通过反射机制,获得代理类的构造方法,方法签名为 getConstructor(InvocationHandler.class)
; -
通过构造函数,获得代理对象,并将自定义的 InvocationHandler
实例对象传为参数传入; -
通过代理对象,调用目标方法。
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—