Dubbo之Wrapper生成的子类字节码
2018-07-07 本文已影响0人
jerrik
直接上图
public class JavassistProxyFactory extends AbstractProxyFactory {
@SuppressWarnings("unchecked")
public <T> T getProxy(Invoker<T> invoker, Class<?>[] interfaces) {
return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
}
public <T> Invoker<T> getInvoker(T proxy, Class<T> type, URL url) {
// TODO Wrapper类不能正确处理带$的类名
final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type);
return new AbstractProxyInvoker<T>(proxy, type, url) {
@Override
protected Object doInvoke(T proxy, String methodName,
Class<?>[] parameterTypes,
Object[] arguments) throws Throwable {
return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
}
};
}
}
Dubbo在创建Invoker的时候先将ref实现类包装成了一个Wrapper,然后Invoker被调用的时候会触发doInvoke()方法,然后调用Wrapper的invokeMethod()方法。由于Wrapper是一个抽象类,故Wrapper.getWrapper()被调用的时候肯定是利用了字节码增强的技术为Wrapper创建了一个实现类。
查看实现类代码
由于Wrapper子类生成是利用javassist技术来实现的,所以直接将字节码输出到文件Wrapper20.java(最好使用IDEA自带的反编译插件,本人jd显示有问题).
package com.xx.xx.samples.loader;
import com.alibaba.dubbo.common.bytecode.NoSuchPropertyException;
import com.xx.xx.samples.loader.ClassGenerator2.DC;
import com.xx.xx.samples.loader.service.impl.UserServiceImpl;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
public class Wrapper20 extends Wrapper2 implements DC {
public static String[] pns;
public static Map pts;
public static String[] mns;
public static String[] dmns;
public static Class[] mts0;
public static Class[] mts1;
public static Class[] mts2;
public String[] getPropertyNames() {
return pns;
}
public boolean hasProperty(String var1) {
return pts.containsKey(var1);
}
public Class getPropertyType(String var1) {
return (Class)pts.get(var1);
}
public String[] getMethodNames() {
return mns;
}
public String[] getDeclaredMethodNames() {
return dmns;
}
public void setPropertyValue(Object var1, String var2, Object var3) {
try {
UserServiceImpl var4 = (UserServiceImpl)var1;
} catch (Throwable var6) {
throw new IllegalArgumentException(var6);
}
throw new NoSuchPropertyException("Not found property \"" + var2 + "\" filed or setter method in class com.xx.xx.samples.loader.service.impl.UserServiceImpl.");
}
public Object getPropertyValue(Object var1, String var2) {
try {
UserServiceImpl var3 = (UserServiceImpl)var1;
} catch (Throwable var5) {
throw new IllegalArgumentException(var5);
}
throw new NoSuchPropertyException("Not found property \"" + var2 + "\" filed or setter method in class com.xx.xx.samples.loader.service.impl.UserServiceImpl.");
}
public Object invokeMethod(Object var1, String var2, Class[] var3, Object[] var4) throws InvocationTargetException {
UserServiceImpl var5;
try {
var5 = (UserServiceImpl)var1;
} catch (Throwable var8) {
throw new IllegalArgumentException(var8);
}
try {
if ("findUserList".equals(var2) && var3.length == 0) {
return var5.findUserList();
}
if ("findById".equals(var2) && var3.length == 1) {
return var5.findById((Integer)var4[0]);
}
if ("updateById".equals(var2) && var3.length == 1) {
var5.updateById((Integer)var4[0]);
return null;
}
} catch (Throwable var9) {
throw new InvocationTargetException(var9);
}
throw new NoSuchMethodException("Not found method \"" + var2 + "\" in class com.xx.xx.samples.loader.service.impl.UserServiceImpl.");
}
public Wrapper20() {
}
}
可知invokeMethod只是做了一次转发,深层次的作用等待挖掘。。。