JDK的动态代理实现原理理解
利用JDK字节码技术生成代理类,代理类调用方法依赖InvocationHandler . 在InvocationHandler里面实现需要增强的业务逻辑以及调用具体的实现类对象的方法.
接口定义:
package org.zheng.cal.parse;
import java.io.File;
import org.zheng.cal.task.StackParserTask;
public interface LogParser {
public void parse(File filePath, StackParserTask currentTask)
throws Exception;
}
1. 根据接口 LogParser 生成代理类 的 Class.如下 Proxy123 (jdk自身实现)
public final class Proxy123
extends Proxy
implements LogParser
{
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
public Proxy123(InvocationHandler paramInvocationHandler)
{
super(paramInvocationHandler);
}
public final boolean equals(Object paramObject)
{
try
{
return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final void parse(File paramFile, StackParserTask paramStackParserTask)
throws Exception
{
try
{
this.h.invoke(this, m3, new Object[] { paramFile, paramStackParserTask });
return;
}
catch (Error|Exception localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final String toString()
{
try
{
return (String)this.h.invoke(this, m2, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final int hashCode()
{
try
{
return ((Integer)this.h.invoke(this, m0, null)).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
static
{
try
{
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m3 = Class.forName("org.zheng.cal.parse.LogParser").getMethod("parse", new Class[] { Class.forName("java.io.File"), Class.forName("org.zheng.cal.task.StackParserTask") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
}
catch (NoSuchMethodException localNoSuchMethodException)
{
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException)
{
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
}
2. 实例化代理类传入参数,InvocationHandler实例.
package org.zheng.cal.factory;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import org.zheng.cal.advice.Advice;
public class DefaultInvocationHandler implements InvocationHandler{
private Object realObj;
private List<Advice> adviceList;
public DefaultInvocationHandler(Object realObj,List<Advice> adviceList){
this.realObj=realObj;
this.adviceList=adviceList;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//TODO ;
for(Advice advice:adviceList){
advice.process(method);
}
Object obj=null;
try {
obj= method.invoke(realObj, args);
} catch (Exception e) {
// TODO Auto-generated catch block
if( e instanceof InvocationTargetException){
throw e.getCause();
}
}
return obj;
}
}
3. 上述为构建代理对象步骤,调用顺序为eg: proxyObject.toString()->handler.invoke(Method,args)-> Method.invoke(realObject,args);
Proxy123 /LogParse proxyObject
--InvocationHandler handler
--StackLogParse realObject