参考答案
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—
