动态代理:其实就是java.lang.reflect.Proxy类动态的根据您指定的所有接口生成一个class byte,该class会继承Proxy类,并实现所有你指定的接口(您在参数中传入的接口数组);然后再利用您指定的classloader将 class byte加载进系统,最后生成这样一个类的对象,并初始化该对象的一些值,如invocationHandler,以即所有的接口对应的Method成员。 初始化之后将对象返回给调用的客户端。这样客户端拿到的就是一个实现你所有的接口的Proxy对象
下面写一个demo:
父接口如下:
package wxtest.proxy; public interface Character { public void run(); public void eat(); }
子类如下:
class Student implements Character { private String name; public Student(String name) { this.name = name; } public void eat() { System.out.println("开始吃饭"); } @Override public void run() { try { Thread.sleep(1000); //假设上交学费时间花了1s } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + "上交学费10000"); }
代理StuInvocationHandler类如下 :
package wxtest.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class StuInvocationHandler<T> implements InvocationHandler { //invocationHandler持有的被代理对象 T target; public StuInvocationHandler(T target) { this.target = target; } /** * @param proxy 代表动态代理的真正的对象 * @param method 代表正在执行的方法 * @param args 代表调用目标方法时传入的实参 * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("代理执行" + method.getName() + "方法"); Object result = method.invoke(target, args); System.out.println(result); return null; } }
测试代码如下:
public class dynamicProxy { public static void main(String[] args) { //被代理的学生Jet,这个对象是被代理的对象 Character jet = new Student("jet"); //父类引用指向子类 //创建一个与代理对象相关联的InvocationHandler InvocationHandler studentHandler = new StuInvocationHandler <Character>(jet); //创建该接口的代理类 //创建一个代理对象stuProxy来代理jet,代理对象的每个执行方法都会替换执行Invocation中invoke方法 Character stuProxy = (Character) Proxy.newProxyInstance(Character.class.getClassLoader(), new Class <?>[]{Character.class}, studentHandler); //代理执行上交班费的方法 stuProxy.run(); stuProxy.eat(); } }
输出结果如下:
代理执行run方法
jet上交学费10000
null
代理执行eat方法
开始吃饭
null