This commit is contained in:
crusader 2018-04-24 16:20:03 +09:00
parent 45375ef6fa
commit 0d87d36859
5 changed files with 234 additions and 4 deletions

View File

@ -0,0 +1,12 @@
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

@ -8,5 +8,5 @@ import com.loafle.commons.rpc.protocol.RPCRegistryCodec;
*/
public interface RPCInvoker {
boolean hasMethod(String method);
Object invoke(RPCRegistryCodec codec, Object... leadingParams) throws RPCException;
Object invoke(RPCRegistryCodec codec) throws RPCException;
}

View File

@ -8,8 +8,8 @@ import com.loafle.commons.rpc.RPCException;
* RPCRegistry
*/
public interface RPCRegistry extends RPCInvoker {
Object getService(String name);
void registerService(Object receiver) throws RPCException;
void registerService(Object receiver, String name) throws RPCException;
void registerServices(Object... receivers) throws RPCException;
void registerServices(Map<String, Object> receivers) throws RPCException;
void registerService(Object receiver, Class<?> receiverClass) throws RPCException;
void registerService(Object receiver, Class<?> receiverClass, String name) throws RPCException;
}

View File

@ -0,0 +1,68 @@
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

@ -0,0 +1,150 @@
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;
}
}
}