动态代理的使用,反射是动态语言的关键
TestDynamicProxy
package com.aff.dynamic; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /* 动态代理是指客户通过代理类来调用其它对象的方法, 并且是在程序运行时根据需要动态创建目标类的代理对象。 动态代理使用场合: 调试 远程方法调用 代理设计模式的原理: 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上。 */ //动态代理的使用,反射是动态语言的关键 interface Subject { void action(); } // 被代理类 class RealSubject implements Subject { public void action() { System.out.println("我是被代理类,记得要执行"); } } //代理类 class MyInvocationHandler implements InvocationHandler { Object obj;// 实现了接口的 被代理类的 对象的声明 // ①给被代理类的对象实例化 // ②返回一个代理类的对象 public Object blind(Object obj) { this.obj = obj; // Proxy:代理类 // Proxy.newProxyInstance :new一个代理类的实例,也要实现 对应被代理类的 实现接口里的抽象方法 // obj.getClass().getClassLoader(): 和obj的类加载器是一样的,obj是和被代理类的对象类加载器相同的 // obj.getClass().getInterfaces(); 被代理类实现的什么接口, 代理类(Proxy)也一样 // this : 实现了InvocationHandler接口的类对象,也就是MyInvocationHandler // 这一步真正的返回一个代理类的对象 return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); } // 每当代理类的对象调用 被重写的action方法时,就会被转化为对如下invoke方法的调用 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //returnVal 返回值相当于被代理类的抽象方法(action)的返回值 Object returnVal = method.invoke(obj, args);//obj 被代理类的 return returnVal; } } public class TestDynamicProxy { public static void main(String[] args) { //1.被代理类的对象 RealSubject real= new RealSubject(); //2.创建一个实现 InvocationHandler接口的类对象 MyInvocationHandler handler = new MyInvocationHandler(); //3.调用blind()方法,动态的返回一个同样实现了real所在类 实现的接口 的代理的对象 Object obj = handler.blind(real);//real 是Subject类型,用Object来接收 Subject sub = (Subject)obj;//得强转一下再调用action,此时的sub 就是代理类的对象、 sub.action();//转到对 InvocationHandler接口的实现类(MyInvocationHandler)的invoke()方法的调用 } }