스스로 Dubbo Invoker 실현
23932 단어 자기가 쓴 틀
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
세부 사항
JavassistProxy Factory 는 Invoker (실행 기) 를 구성 하 는 데 사 용 됩 니 다. dubbo 는 ExtensionLoader 로 JavassistProxy Factory 를 구성 합 니 다. 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;
}
}
AbstractProxy Invoker 실행 기 구현, 중요
/***
*
*
* @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 는 인터페이스 클 라 스 를 포장 하 는 독립 적 인 추상 적 인 클래스 입 니 다. (위 에서 말 한 IUserService)여기 서 class 작업 에 대해 우 리 는 몇 가지 작업 을 추상 화 할 수 있 습 니 다. 1. class 의 모든 필드 의 이름 을 가 져 옵 니 다: abstract Public String [] getProperty Names ();
2. 필드 이름 에 따라 필드 형식 가 져 오기: abstract public Class getProperty Type (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 set PropertyValue (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 의 실현 류 Wrapper 0 을 구성 하여 상기 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