读书人

模拟兑现Java动态代理机制

发布时间: 2012-09-17 12:06:51 作者: rapoo

模拟实现Java动态代理机制

? 前一篇文章我们分析了Java Proxy动态代理类,只是从表面知道他就是打着他人的旗帜,干着自己的勾当!模拟兑现Java动态代理机制但是本质上还没有搞清楚它的非法运营模式,这一章我们就来模拟一下犯罪现场,以及解决前一章遗留的问题。模拟开始先~

?

??? 一、定义委托高层接口

?

/** * 模拟Java动态代理机制 */package com.demo.delegator;/** * 定义委托高层接口 * @author Andy * @since 2012.02.17 15:59 PM * @version 1.0 * */public final class IDelegator {/** * 接口一 * */public static interface One{public void sing();}/** * 接口二 * */public static interface Two{public int write();}/** * 接口三 *  */public static interface Three{public String read();}}

?

??? 二、定义委托实现类

?

/** * 模拟java动态代理机制 */package com.demo.delegator.impl;import com.demo.delegator.IDelegator;/** * 委托实现类 *  * @author Andy * @seecom.demo.delegator.IDelegator.One * @seecom.demo.delegator.IDelegator.Two * @seecom.demo.delegator.IDelegator.Three * @since 2012.02.17 15:59 PM * @version 1.0 */public class DelegatorImpl implements IDelegator.One , IDelegator.Two , IDelegator.Three {@Overridepublic String read() {this.print();return "";}@Overridepublic int write() {this.print();return 0;}@Overridepublic void sing() {this.print();}private void print(){String message = "Invoke " + Thread.currentThread().getStackTrace()[2].getClassName() + "." + Thread.currentThread().getStackTrace()[2].getMethodName();System.out.println(message);}}

?

? ? ?? 三、定义代理类

?

?

/** * 模拟Java动态代理机制 */package com.demo.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import com.demo.delegator.IDelegator;/** * 模拟JAVA动态代理类 *  *  * JAVA原生动态代理类由ProxyGenerator动态生成实现代理接口的字节码,并注入classloader中。 * 参见源码: * String proxyName = proxyPkg + "$proxy" + num; * byte[] proxyClassFile =ProxyGenerator.generateProxyClass(proxyName, interfaces); * proxyClass = defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length); *  * 代理机制: * 代理类和委托代理类都实现了代理接口,当代理类调用代理接口时,首先会触发调用处理程序。 * 再由处理程序分发调用委托代理类的接口。从而实现了代理类对委托代理类的隔离。 *  * @author Andy * @seecom.demo.delegator.IDelegator.One * @seecom.demo.delegator.IDelegator.Two * @seecom.demo.delegator.IDelegator.Three * @since 2012.02.17 15:59 PM * @version 1.0 */public final class DynamicProxy implements IDelegator.One , IDelegator.Two , IDelegator.Three {// 引用调用处理对象private static InvocationHandler handler;private static Class<?>[] interfaces = null;        private static Map<Class<?>, DynamicProxy> cachMap = Collections.synchronizedMap(new HashMap<Class<?> , DynamicProxy>());       ?private DynamicProxy(Class<?>[] interfaces , InvocationHandler handler){DynamicProxy.handler = handler;DynamicProxy.interfaces = interfaces;}public static Object newInstance(Class<?> clazz, Class<?>[] interfaces,InvocationHandler handler){DynamicProxy proxy = cachMap.get(clazz);if(null == proxy){proxy = new DynamicProxy(interfaces , handler);cachMap.put(clazz, proxy);}return proxy;}@Overridepublic String read() {return String.valueOf(this.invoke());}@Overridepublic int write() {return Integer.valueOf(this.invoke().toString());}@Overridepublic void sing() {this.invoke();}private Object invoke(){Object obj = null;try {StackTraceElement[] elements = Thread.currentThread().getStackTrace();String methodName = elements[2].getMethodName();for (int i = 0; i < interfaces.length; i++) {Class<?> clazz = interfaces[i];Method[] methods = clazz.getMethods();for (int j = 0; j < methods.length; j++) {Method method = methods[j];if(methodName.equals(method.getName())){Class<?> args[] = method.getParameterTypes();obj = handler.invoke(this, method, args);break;}}}return obj;} catch (SecurityException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NoSuchMethodException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (Throwable e) {// TODO Auto-generated catch blocke.printStackTrace();}return null;}}

?

?? 四、定义委托调用处理程序

?

/** *  */package com.demo.proxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;/** * 委托接口调用处理程序 *  * @author Andy * @seejava.lang.reflect.InvocationHandler * @since 2012.02.17 15:59 PM * @version 1.0 */public class AOPHandler implements InvocationHandler {private Object instance = null;private AOPHandler(Class<?> clazz){try {this.instance = clazz.newInstance();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static Object getProxyInstance(Class<?> clazz , Class<?> interfaces[]){return DynamicProxy.newInstance(clazz , interfaces , new AOPHandler(clazz));}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println(method.getName() + " invoke start.");Object returnValue = method.invoke(this.instance, args);System.out.println(method.getName() + " invoke end.");return returnValue;}}
?

?

?? 五、模拟代理测试类

?

/** * 模拟Java动态代理机制 */package com.demo;import com.demo.delegator.IDelegator;import com.demo.delegator.impl.DelegatorImpl;import com.demo.proxy.AOPHandler;/** * 代理测试类 * @author Andy * */public class ProxyTest {/** * @param args */public static void main(String[] args) {// 创建调用处理程序IDelegator.One proxy = (IDelegator.One)AOPHandler.getProxyInstance(DelegatorImpl.class , DelegatorImpl.class.getInterfaces());proxy.sing();}}
?

?

?? 总结:委托类与代理类都实现了委托高层接口,故代理类可以处理委托类的请求。当代理类拦截到接口请求时,首先进行委托调用处理程序(所谓的拦截器),在委托调用处理程序中才真正决定是否分发委托类的请求。代理就这样轻松的实现了委托授权,隔离委托类的直接调用。

?? 分析了代理的机制,上一章ProxyGenerator.generateProxyClass(String s, Class clazz[])也不再是个谜。不难推测它就是Proxy的帮凶(子类),并动态实现委托接口,充当代码生成器的凶手。

?

?

读书人网 >编程

热点推荐