1.Dubbo Invoker 用来执行spring注入的业务接口的实现类的方法。下面我来自己实现一套。基本上是dubbo的设计模式思想。
2.先看下使用说明:
//User 对象
class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
// 业务 user接口
interface IUserSerice {
public User login(User user);
}
// 接口实现
class UserServiceImpl implements IUserSerice {
@Override
public User login(User user) {
System.err.println(user.getName() + " login....");
user.setName("login success");
return user;
}
}
public static void main(String[] args) {
// 模仿spring new 业务对象
IUserSerice userSerice = new UserServiceImpl();
User user = new User();
user.setName("hadluo");
// 用构造 IUserSerice 接口 对应的 Invoker ,dubbo是extensionloader构造的,这里我们直接模拟.
Invoker invoker = JavassistProxyFactory.getInvoker(userSerice, IUserSerice.class);
//构造调用方法信息,Invocation是调用方法信息,我们这里是 login方法信息
Invocation invocation = new NativeInvocation("login",new Class>[]{User.class},new Object[]{user}) ;
//执行一次 本地调用
Result result = invoker.invoker(invocation);
System.err.println("返回 值:" + ((User)result.getResult()).getName());
}
//###########结果
hadluo login....
返回值:login success
JavassistProxyFactory
用来构造Invoker(执行器) , dubbo是 用ExtensionLoader来构造JavassistProxyFactory 的,ExtensionLoader的实现 见另一篇: https://blog.csdn.net/luozheng4698729/article/details/80070630
public class JavassistProxyFactory {
// proxy: UserServiceImpl实例对象 , type: IUserService接口的class
public static Invoker getInvoker(T proxy, Class> type) {
// Wrapperd 是对 IUserService接口 的包装操作,后面会细讲
final Wrapper wrapper = Wrapper.getWrapper(type);
return new AbstractProxyInvoker(type, proxy) {
@Override
public Object doInvoke(Object proxy, Invocation invocation) throws Throwable {
return wrapper.invokeMethod(proxy, invocation.getMethodName(),
invocation.getParameterTypes(), invocation.getArguments());
}
};
}
}
Invoker
执行器 接口
public interface Invoker{
// 执行方法, Invocation 为执行信息(包括执行 哪个方法,参数等信息),Result为执行结果
Result invoker(Invocation invocation);
// 省略其它 dubbo中的方法
}
Invocation
执行 方法信息 ,dubbo里面包括本地 方法执行 信息类型和 RPC方法执行信息类型。
/***
* 执行 方法信息 (参数,返回值,方法名)
*
* @author HadLuo
* @since JDK1.7
* @history 2018年4月27日 新建
*/
public interface Invocation {
// 获取执行的方法名称
String getMethodName();
// 获取方法 参数 类型
Class>[] getParameterTypes();
//获取方法 参数
Object[] getArguments();
}
// 本地 方法执行 信息类型, 我们就写一个
public class NativeInvocation implements Invocation {
private String methodName;
private Class>[] parameterTypes;
private Object[] arguments;
public NativeInvocation(String methodName, Class>[] parameterTypes, Object[] arguments) {
super();
this.methodName = methodName;
this.parameterTypes = parameterTypes;
this.arguments = arguments;
}
@Override
public String getMethodName() {
return methodName;
}
@Override
public Class>[] getParameterTypes() {
return parameterTypes;
}
@Override
public Object[] getArguments() {
return arguments;
}
}
Result
执行器Invoker 的执行结果,与Invocation对应,包括本地执行结果,rpc执行结果
/***
* 执行器Invoker 的执行结果
*
* @author HadLuo
* @since JDK1.7
* @history 2018年4月27日 新建
*/
public interface Result {
public Object getResult();
}
// 这里 我们 就写 一个 本地执行结果
public class RpcResult implements Result {
private Object object;
public RpcResult(Object object) {
this.object = object;
}
@Override
public Object getResult() {
return object;
}
}
AbstractProxyInvoker
执行器实现,很重要
/***
* 抽象 代理 执行 器
*
* @author HadLuo
* @since JDK1.7
* @history 2018年4月27日 新建
*/
public abstract class AbstractProxyInvoker<T> implements Invoker<T> {
// spring注入的业务对象,也就是上面的 UserServiceImpl对象
private final T object;
public AbstractProxyInvoker(Class> type, T object) {
this.object = object;
}
/***
* 抽象 执行方法 ,交给 Wrapper实现
*
* @param proxy
* @param invocation
* @return
* @throws Throwable
* @author HadLuo 2018年4月27日 新建
*/
public abstract Object doInvoke(Object proxy, Invocation invocation) throws Throwable;
@Override
public Result invoker(Invocation invocation) {
if (invocation instanceof NativeInvocation) {
try {
// 间接调用 doInvoke 方法
return new RpcResult(doInvoke(object, invocation));
} catch (Throwable e) {
e.printStackTrace();
}
}
if(invocation instanceof RpcInvocation){
// 远程调用, 这里先不管
}
throw new RuntimeException("暂时 只 实现 本地的 调用");
}
}
Wrapper
Wrapper是一个独立的抽象类, 用来 包装对接口class的操作(上面我们说的IUserService)。这里对class操作,我们可以抽象几种操作:
1.获取class中所有字段的名称 : abstract public String[] getPropertyNames();
2.根据字段名称获取字段类型:abstract public Class getPropertyType(String pn);
3.判断class中是否存在某字段:abstract public boolean hasProperty(String name);
4.获取class对象的某字段的值:abstract public Object getPropertyValue(Object instance, String pn) throws Throwable;
5.设置字段的值:abstract public void setPropertyValue(Object instance, String pn, Object pv) throws Throwable;
6.执行方法:abstract public Object invokeMethod(Object instance, String methodName, Class[] types, Object[] args) throws Throwable;
很明显第6条才是最重要的。实现原理就是动态构造一个Wrapper的实现类Wrapper0来实现上述6个抽象方法的 , 下面我们看下怎么实现这些方法的:
public abstract class Wrapper {
//动态类名称,Wrapper0 的 0 调一次 就加1, 依次是:Wrapper0,Wrapper1,Wrapper2...
private static AtomicLong WRAPPER_CLASS_COUNTER = new AtomicLong(0);
// 缓存, key: IUserService接口class, value: 动态类
private static ConcurrentHashMap, Wrapper> WRAPPERS = new ConcurrentHashMap, Wrapper>();
public static Wrapper getWrapper(Class> type) {
Wrapper wrapper = WRAPPERS.get(type);
if (wrapper == null) {
// 动态实现类
wrapper = makeWrapper(type);
//加入缓存
WRAPPERS.putIfAbsent(type, wrapper);
}
return wrapper;
}
abstract public String[] getPropertyNames();
abstract public Class> getPropertyType(String pn);
abstract public boolean hasProperty(String name);
abstract public Object getPropertyValue(Object instance, String pn) throws Throwable;
abstract public void setPropertyValue(Object instance, String pn, Object pv) throws Throwable;
abstract public Object invokeMethod(Object instance, String methodName, Class>[] types, Object[] args) throws Throwable;
private static Wrapper makeWrapper(Class> type) {
//这个 ClassGenerator 是dubbo写的动态类构造工具,使用javassist底层实现,工具我放在文章最后
ClassGenerator classGenerator = ClassGenerator.newInstance(Wrapper.class.getClassLoader());
// extends Wrapper.class
classGenerator.setSuperClass(Wrapper.class);
// class 名称
classGenerator.setClassName(Wrapper.class.getName() + WRAPPER_CLASS_COUNTER.getAndIncrement() + "$");
// public static Map> pts; // key: 属性名称 value:属性类型
classGenerator.addField("public static " + Map.class.getName() + " pts;");
// 属性名称 集合
classGenerator.addField("public static String[] pNames;");
// getPropertyNames 抽象方法实现
classGenerator.addMethod("public String[] getPropertyNames(){return pNames;}");
// getPropertyType 抽象方法实现
classGenerator.addMethod("public Class getPropertyType(String pName) { return (Class)pts.get(pName); }");
// hasProperty 抽象方法实现
classGenerator
.addMethod("public boolean hasProperty(String name){ return pts.containsKey(name) ; }");
// getPropertyValue 抽象方法实现
classGenerator
.addMethod("public Object getPropertyValue(Object instance, String pName) throws Throwable { "
+ "try {"
+ "java.lang.Class clazz = instance.getClass();"
+ "java.lang.reflect.Field f = clazz.getDeclaredField(pName);"
+ "return f.get(instance);" + "} catch (Exception e) {throw e;} }");
// setPropertyValue 抽象方法实现
classGenerator
.addMethod("public void setPropertyValue(Object instance, String pName, Object pValue) throws Throwable {"
+ "try {"
+ "java.lang.reflect.Field f = instance.getClass().getDeclaredField(pName);"
+ "f.set(instance, pValue);" + "} catch (Exception e) { throw e;}}");
// invokeMethod 抽象方法实现
classGenerator
.addMethod("public Object invokeMethod(Object instance, String methodName, Class[] types, Object[] args) throws Throwable {"
+ "try {"
+ "java.lang.Class clazz = instance.getClass();"
+ "java.lang.reflect.Method method = clazz.getDeclaredMethod(methodName, types);"
+ "if (method == null) { throw new NullPointerException(\"没有 在 \" + clazz.getName() + \" 中 找到 方法: \" + methodName);}"
+ "return method.invoke(instance, args);" + "} catch (Exception e) {throw e;}}");
try {
Class> proxyClass = classGenerator.toClass();
if (proxyClass == null) {
throw new RuntimeException("生成动态类型错误");
}
Map> pts = new HashMap>();
for (Field f : type.getDeclaredFields()) {
pts.put(f.getName(), f.getType());
}
// 跟动态类 的静态字段设置值
proxyClass.getDeclaredField("pts").set(null, pts);
proxyClass.getDeclaredField("pNames").set(null, pts.keySet().toArray(new String[0]));
return (Wrapper) proxyClass.newInstance();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
上述动态构造类的代码不必深究,其实就是构造如下类(实现也很简单):
// 生成的动态类==============
class Wrapper0 extends Wrapper {
// key: 属性名称 value:属性类型
public static Map> pts;
// 属性名称
public static String[] pNames;
@Override
public Object invokeMethod(Object instance, String methodName, Class>[] types, Object[] args)
throws Throwable {
try {
java.lang.Class clazz = instance.getClass();
java.lang.reflect.Method method = clazz.getDeclaredMethod(methodName, types);
if (method == null) {
throw new NullPointerException("没有 在 " + clazz.getName() + " 中 找到 方法: " + methodName);
}
return method.invoke(instance, args);
} catch (Exception e) {
throw e;
}
}
@Override
public String[] getPropertyNames() {
return pNames;
}
@Override
public Class> getPropertyType(String pName) {
return pts.get(pName);
}
@Override
public boolean hasProperty(String name) {
return pts.containsKey(name);
}
@Override
public Object getPropertyValue(Object instance, String pName) throws Throwable {
try {
java.lang.Class clazz = instance.getClass();
java.lang.reflect.Field f = clazz.getDeclaredField(pName);
return f.get(instance);
} catch (Exception e) {
throw e;
}
}
@Override
public void setPropertyValue(Object instance, String pName, Object pValue) throws Throwable {
try {
java.lang.reflect.Field f = instance.getClass().getDeclaredField(pName);
f.set(instance, pValue);
} catch (Exception e) {
throw e;
}
}
}
上述就是所有实现细节,跟Dubbo肯定有点差异,不必较真,主要是思想一致。要工程源码加我: 657455400 csdn下载链接:https://download.csdn.net/download/luozheng4698729/10379503