您的位置:首页 > 编程语言 > Java开发

模拟实现Java动态代理机制

2012-11-02 10:17 726 查看
前一篇文章 我们分析了Java Proxy动态代理类,只是从表面知道他就是打着他人的旗帜,干着自己的勾当!

但是本质上还没有搞清楚它的非法运营模式,这一章我们就来模拟一下犯罪现场,以及解决前一章遗留的问题。模拟开始先~

一、定义委托高层接口

/**
* 模拟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
* @see com.demo.delegator.IDelegator.One
* @see com.demo.delegator.IDelegator.Two
* @see com.demo.delegator.IDelegator.Three
* @since 2012.02.17 15:59 PM
* @version 1.0
*/
public class DelegatorImpl implements IDelegator.One , IDelegator.Two , IDelegator.Three {

@Override
public String read() {
this.print();
return "";
}

@Override
public int write() {
this.print();
return 0;
}

@Override
public 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
* @see com.demo.delegator.IDelegator.One
* @see com.demo.delegator.IDelegator.Two
* @see com.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;
}

@Override
public String read() {
return String.valueOf(this.invoke());
}

@Override
public int write() {
return Integer.valueOf(this.invoke().toString());
}

@Override
public 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 block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}

}


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

/**
*
*/
package com.demo.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
* 委托接口调用处理程序
*
* @author Andy
* @see java.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 block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public static Object getProxyInstance(Class<?> clazz , Class<?> interfaces[]){
return DynamicProxy.newInstance(clazz , interfaces , new AOPHandler(clazz));
}

@Override
public 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的帮凶(子类),并动态实现委托接口,充当代码生成器的凶手。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: