This commit is contained in:
crusader 2018-04-25 20:29:42 +09:00
parent 35f8e422b8
commit 2d761824a7
4 changed files with 126 additions and 235 deletions

View File

@ -1,12 +0,0 @@
package com.loafle.commons.rpc.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RPCMethod {
String value() default "";
}

View File

@ -1,15 +1,136 @@
package com.loafle.commons.rpc.registry; package com.loafle.commons.rpc.registry;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.loafle.commons.rpc.RPCException; import com.loafle.commons.rpc.RPCException;
import com.loafle.commons.rpc.protocol.RPCRegistryCodec;
/** /**
* RPCRegistry * RPCRegistry
*/ */
public interface RPCRegistry extends RPCInvoker { public class RPCRegistry implements RPCInvoker {
void registerService(Object receiver) throws RPCException; private Map<String, RPCService> services;
void registerService(Object receiver, String name) throws RPCException;
void registerService(Object receiver, Class<?> receiverClass) throws RPCException; public RPCRegistry() {
void registerService(Object receiver, Class<?> receiverClass, String name) throws RPCException; this.services = new HashMap<>();
}
public RPCService registerService(Object receiver) throws RPCException {
if (null == receiver) {
throw new RPCException("receiver is null");
}
return this.registerService(receiver, receiver.getClass().getName());
}
public RPCService registerService(Object receiver, String name) throws RPCException {
if (null == receiver) {
throw new RPCException("receiver is null");
}
RPCService rService = new RPCService();
rService.instance = receiver;
this.services.put(name, rService);
return rService;
}
@Override
public boolean hasMethod(String method) {
String[] sm = method.split(".");
if (null == sm || 2 != sm.length) {
return false;
}
RPCService rService = this.services.get(sm[0]);
if (null == rService) {
return false;
}
RPCServiceMethod rServiceMethod = rService.getServiceMethod(sm[1]);
if (null == rServiceMethod) {
return false;
}
return true;
}
@Override
public Object invoke(RPCRegistryCodec codec) throws RPCException {
String method = codec.method();
String[] sm = method.split(".");
if (null == sm || 2 != sm.length) {
throw new RPCException(String.format("method[%s] is not valid", method));
}
RPCService rService = this.services.get(sm[0]);
if (null == rService) {
throw new RPCException(String.format("service[%s] is not exist", sm[0]));
}
RPCServiceMethod rServiceMethod = rService.getServiceMethod(sm[1]);
if (null == rServiceMethod) {
throw new RPCException(String.format("method[%s] of service[%s] is not exist", sm[1], sm[0]));
}
Type[] parameterTypes = rServiceMethod.getParameterTypes();
Object[] params = codec.params(parameterTypes);
try {
return rServiceMethod.method.invoke(rService.instance, params);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RPCException(String.format("Cannot invoke method[%s] with params[%s]", method, params), e);
}
}
public static class RPCService {
private Object instance;
private Map<String, RPCServiceMethod> methods;
RPCService() {
this.methods = new HashMap<>();
}
public Object getInstance() {
return this.instance;
}
public void registerMethod(Method method) {
this.registerMethod(method, method.getName());
}
public void registerMethod(Method method, String name) {
RPCServiceMethod rServiceMethod = new RPCServiceMethod();
rServiceMethod.method = method;
rServiceMethod.returnType = method.getReturnType();
rServiceMethod.parameterTypes = method.getGenericParameterTypes();
this.methods.put(name, rServiceMethod);
}
public RPCServiceMethod getServiceMethod(String name) {
return this.methods.get(name);
}
}
public static class RPCServiceMethod {
private Method method;
private Class<?> returnType;
private Type[] parameterTypes;
RPCServiceMethod() {
}
public Method getMethod() {
return this.method;
}
public Class<?> getReturnType() {
return this.returnType;
}
public Type[] getParameterTypes() {
return this.parameterTypes;
}
}
} }

View File

@ -1,68 +0,0 @@
package com.loafle.commons.rpc.registry.pojo;
import java.lang.reflect.Type;
import com.loafle.commons.rpc.RPCException;
import com.loafle.commons.rpc.protocol.RPCRegistryCodec;
import com.loafle.commons.rpc.registry.RPCRegistry;
import com.loafle.commons.rpc.util.RPCServiceRegistry;
/**
* POJORPCRegistry
*/
public class POJORPCRegistry implements RPCRegistry {
private RPCServiceRegistry serviceRegistry;
public POJORPCRegistry() {
this.serviceRegistry = new RPCServiceRegistry();
}
@Override
public void registerService(Object receiver) throws RPCException {
if (null == receiver) {
throw new RPCException("receiver is null");
}
this.registerService(receiver, receiver.getClass());
}
@Override
public void registerService(Object receiver, String name) throws RPCException {
if (null == receiver) {
throw new RPCException("receiver is null");
}
this.registerService(receiver, receiver.getClass(), name);
}
@Override
public void registerService(Object receiver, Class<?> receiverClass) throws RPCException {
if (null == receiver) {
throw new RPCException("receiver is null");
}
this.registerService(receiver, receiverClass, receiverClass.getName());
}
@Override
public void registerService(Object receiver, Class<?> receiverClass, String name) throws RPCException {
this.serviceRegistry.register(receiver, receiverClass, name);
}
@Override
public boolean hasMethod(String method) {
return this.serviceRegistry.hasMethod(method);
}
@Override
public Object invoke(RPCRegistryCodec codec) throws RPCException {
String method = codec.method();
if (!this.serviceRegistry.hasMethod(method)) {
throw new RPCException(String.format("method[%s] is not exist", method));
}
Type[] parameterTypes = this.serviceRegistry.getParameterTypes(method);
Object[] params = codec.params(parameterTypes);
Object result = this.serviceRegistry.invoke(method, params);
return result;
}
}

View File

@ -1,150 +0,0 @@
package com.loafle.commons.rpc.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import com.loafle.commons.rpc.RPCException;
import com.loafle.commons.rpc.annotation.RPCMethod;
/**
* RPCServiceRegistry
*/
public class RPCServiceRegistry {
private Map<String, RPCServiceMeta> services;
public RPCServiceRegistry() {
this.services = new HashMap<>();
}
public void register(Object receiver, Class<?> receiverClass, String name) throws RPCException {
if (null == receiver) {
throw new RPCException("receiver is null");
}
String sName = name;
if ("" == sName.trim()) {
sName = receiverClass.getName();
}
RPCServiceMeta serviceMeta = new RPCServiceMeta();
serviceMeta.instance = receiver;
Method[] methods = receiverClass.getMethods();
for (Method method : methods) {
RPCMethod a = method.getAnnotation(RPCMethod.class);
if (null == a) {
continue;
}
RPCServiceMethodMeta methodMeta = new RPCServiceMethodMeta();
methodMeta.method = method;
methodMeta.returnType = method.getReturnType();
methodMeta.parameterTypes = method.getGenericParameterTypes();
String n = "" == a.value() ? method.getName() : a.value();
serviceMeta.methods.put(n, methodMeta);
}
if (0 < serviceMeta.methods.size()) {
this.services.put(sName, serviceMeta);
}
}
public boolean hasMethod(String method) {
String[] sm = method.split(".");
if (null == sm || 2 != sm.length) {
return false;
}
RPCServiceMeta serviceMeta = this.services.get(sm[0]);
if (null == serviceMeta) {
return false;
}
RPCServiceMethodMeta methodMeta = serviceMeta.getMethodMeta(sm[1]);
if (null == methodMeta) {
return false;
}
return true;
}
public Type[] getParameterTypes(String method) throws RPCException {
String[] sm = method.split(".");
if (null == sm || 2 != sm.length) {
throw new RPCException(String.format("method[%s] is not valid", method));
}
RPCServiceMeta serviceMeta = this.services.get(sm[0]);
if (null == serviceMeta) {
throw new RPCException(String.format("service[%s] is not exist", sm[0]));
}
RPCServiceMethodMeta methodMeta = serviceMeta.getMethodMeta(sm[1]);
if (null == methodMeta) {
throw new RPCException(String.format("method[%s] of service[%s] is not exist", sm[1], sm[0]));
}
return methodMeta.parameterTypes;
}
public Object invoke(String method, Object... params) throws RPCException {
String[] sm = method.split(".");
if (null == sm || 2 != sm.length) {
throw new RPCException(String.format("method[%s] is not valid", method));
}
RPCServiceMeta serviceMeta = this.services.get(sm[0]);
if (null == serviceMeta) {
throw new RPCException(String.format("service[%s] is not exist", sm[0]));
}
RPCServiceMethodMeta methodMeta = serviceMeta.getMethodMeta(sm[1]);
if (null == methodMeta) {
throw new RPCException(String.format("method[%s] of service[%s] is not exist", sm[1], sm[0]));
}
try {
return methodMeta.method.invoke(serviceMeta.instance, params);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RPCException(String.format("Cannot invoke method[%s] with params[%s]", method, params), e);
}
}
public static class RPCServiceMeta {
private Object instance;
private Map<String, RPCServiceMethodMeta> methods;
RPCServiceMeta() {
this.methods = new HashMap<>();
}
public Object getInstance() {
return this.instance;
}
public RPCServiceMethodMeta getMethodMeta(String name) {
return this.methods.get(name);
}
}
public static class RPCServiceMethodMeta {
private Method method;
private Class<?> returnType;
private Type[] parameterTypes;
RPCServiceMethodMeta() {
}
public Method getMethod() {
return this.method;
}
public Class<?> getReturnType() {
return this.returnType;
}
public Type[] getParameterTypes() {
return this.parameterTypes;
}
}
}