动态代理模式
package com.base.pattern.test; /** * 明星接口,用于给子类实现 * * @author Wei * @time 2016年9月27日 下午9:09:46 */ public interface Star { public void actMovie(); public void sing(); }
被代理类:
package com.base.pattern.test; /** * 真实类,需要被代理的类 * * @author Wei * @time 2016年9月27日 下午9:09:16 */ public class RealStar implements Star { @Override public void actMovie() { System.out.println("RealStar actMovie"); } @Override public void sing() { System.out.println("RealStar sing a song"); } }
被代理类的处理类:
package com.base.pattern.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import com.util.UtilTime; /** * 通过实现 InvocationHandler接口以实现动态代理 就如静态代理一样, 不管是静态代理还是动态代理,都需要传入一个被代理类 * * @author Wei * @time 2016年9月27日 下午9:10:33 */ public class StarHandler implements InvocationHandler { // 声明一个被代理类变量,用于接收构造器里传入的被代理对象 RealStar realStar; /** * 传入被代理类, * * @param realStar */ public StarHandler(RealStar realStar) { this.realStar = realStar; } /** * proxy :不能调用 toString方法,否则会陷入死循环。 * method: 被代理类的方法,用于代码中使用反射 * args: 被代理类的method方法需要用的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 获取代理类的方法名 String methodName = method.getName(); System.out.println(UtilTime.getCurrentTime(null) + "将要真正执行代理的方法:" + methodName); // 固定的写法,调用被代理类的方法 method.invoke(realStar, args); System.out.println(UtilTime.getCurrentTime(null) + "已经执行完代理的方法:" + methodName); System.out.println(); return null; } }
测试类:
package com.base.pattern.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; /** * 代理类测试 * * @author Wei * @time 2016年9月27日 下午10:08:08 */ public class test { public static void main(String[] args) throws InterruptedException { RealStar realStar = new RealStar(); ClassLoader loader = realStar.getClass().getClassLoader(); Class<?>[] interfs = realStar.getClass().getInterfaces(); // 传入被代理类,也就是真正的明星类 InvocationHandler h = new StarHandler(realStar); // 生成代理类,这是至关重要的一步 Star proxy = (Star) Proxy.newProxyInstance(loader, interfs, h); proxy.sing(); Thread.sleep(1000); proxy.actMovie(); } }
控制台输出:
2016.09.27 22:07:55 CST将要真正执行代理的方法:sing
RealStar sing a song
2016.09.27 22:07:55 CST已经执行完代理的方法:sing
2016.09.27 22:07:56 CST将要真正执行代理的方法:actMovie
RealStar actMovie
2016.09.27 22:07:56 CST已经执行完代理的方法:actMovie