Java 动态代理 Demo

时间:2023-12-18 18:08:32

  相比于静态代理,动态代理避免了开发者编写各个繁锁的静态代理类,只需指定一组接口及目标类对象就能动态地获取代理对象。

  

  使用动态代理的六大步骤:

  1 通过实现InvocationHandler接口来自定义自己的InvocationHandler。

  2 通过Proxy类的getProxyClass方法获取代理类。

  3 通过反射机制获取代理类的构造方法,方法签名为getConstructor(InvocationHandler.class)。

  4 将目标对象作为参数传入,通过构造方法获取自定义的InvocationHandler实例对象。

  5 将自定义的InvocationHandler实例对象作为参数传入,通过构造方法获取代理对象。

  6 代理对象调用目标方法。

  JDK Proxy HelloWorld

 package com.yao.proxy;

 public interface Helloworld {
void sayHello();
}
 package com.yao.proxy;

 import com.yao.HelloWorld;

 public class HelloworldImpl implements HelloWorld {
public void sayHello() {
System.out.print("hello world");
}
}
 package com.yao.proxy;

 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;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method :"+ method.getName()+" is invoked!");
return method.invoke(target,args); // 执行相应的目标方法
}
}

  target属性表示代理的目标对象。InvocationHandler是连接代理对象与目标对象的自定义中间类MyInvocationHandler必须实现的接口,只有一个方法public Object invoke(Object proxy, Method method, Object[] args)。在这个方法中,Proxy通过newProxyInstance方法创建代理对象,method表示目标对象被调用的方法,args表示目标对象被调用方法的形参列表。

 package com.yao.proxy;

 import com.yao.HelloWorld;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy; public class JDKProxyTest {
public static void main(String[]args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 这里有两种写法,采用复杂的一种写法,有助于理解。
Class<?> proxyClass= Proxy.getProxyClass(JDKProxyTest.class.getClassLoader(),HelloWorld.class);
final Constructor<?> cons = proxyClass.getConstructor(InvocationHandler.class);
final InvocationHandler ih = new MyInvocationHandler(new HelloworldImpl());
HelloWorld helloWorld = (HelloWorld)cons.newInstance(ih);
helloWorld.sayHello(); // 下面是简单的一种写法,本质上和上面是一样的
/*
HelloWorld helloWorld=(HelloWorld)Proxy.
newProxyInstance(JDKProxyTest.class.getClassLoader(),
new Class<?>[]{HelloWorld.class},
new MyInvocationHandler(new HelloworldImpl()));
helloWorld.sayHello();
*/
} }

  

  参考资料

  深度剖析JDK动态代理机制

  JDK动态代理详解

  JDK动态代理源码解析