1. 先从例子说起
1)抽象角色
//抽象角色类的定义 public interface Subject { public void request(); }
2)目标类,对抽象类的真正实现
/** * 目标类,对抽象类的真正实现 * @author lele * */ public class RealSubject implements Subject { @Override public void request() { System.out.println("From realSubject request"); } }
3)动态代理类DynamicClassimport java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * 该代理类的内部属性是Object类型,实际使用的时候通过该类的构造方法传递进来一个对象 * 此外,该类还实现invoke方法,该类中的method.invoke其实就是调用被代理对象的将要 * 执行的方法,方法参数是sub,表示该方法从属于sub,通过动态代理类,我们可以在执行真实对象的方法前后 * 加入自己的一些额外操作。 * @author lele * */ public class DynamicSubject implements InvocationHandler { //持有真实对象的引用,如果定义成RealSubject,则接受的范围将减小,所以持有Object对象。 private Object sub ; public DynamicSubject(Object obj){ this.sub = obj; } @Override /* * 实现InvocationHandler,则必须实现invoke方法,该方法参数的解释 * Object proxy:一般是指代理类 * Method method:是被代理的方法 * Object[] args:是被代理方法的参数数组 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before calling:"+method); //执行目标类对象sub中的method方法,并传入指定的参数数组args method.invoke(sub, args); System.out.println("after calling"+method); return null; } }
2. 客户端类的定义
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; /** * 客户端类的定义 * @author lele * */ public class Client { /** * @param args */ public static void main(String[] args) { //创建实际要操作的对象 RealSubject realSubject = new RealSubject(); //创建动态代理对象,将实际要操作的对象作为参数交给动态代理对象 InvocationHandler handler = new DynamicSubject(realSubject); //得到动态代理对象对应的Class类的对象classType Class<?> classType = handler.getClass(); /** * 1. Proxy就是动态代理类,相当于静态代理例子中的ProxySubject类 * 2.通过Proxy的静态方法newProxyInstance()来动态创建一个动态代理对象 * 参数说明: * classLoader:类装在器,创建一个具体事例的时候是由哪个类加载器来加载的 * Class<?> interfaces:实际的目标操作类实现的接口 * invocationHandler: 真正执行的实现了InvocationHandler接口的代理对象 * * 因为realSubject对象的类实现了Subject接口,因此也可以说生成的动态代理类也实现了 * Subject接口,因此可以强转成Subject类型 * */ Subject subject = (Subject)Proxy.newProxyInstance(classType.getClassLoader(), realSubject.getClass().getInterfaces(), handler); //通过代理调用方法,这样写就去执行实现了InvocationHandler接口的动态代理对象中的 //invoke方法了 subject.request(); } }
以上!