【不兼容】移除RpcCall、RpcCallAttribute功能

This commit is contained in:
Redkale
2023-01-10 16:12:20 +08:00
parent eeaefb1ed2
commit 8f8a2ef325
10 changed files with 68 additions and 269 deletions

View File

@@ -489,7 +489,7 @@ public abstract class NodeServer {
}
final ResourceTypeLoader resourceLoader = (ResourceFactory rf, String srcResourceName, final Object srcObj, final String resourceName, Field field, final Object attachment) -> {
try {
if (SncpClient.parseMethod(serviceImplClass).isEmpty()
if (SncpClient.parseMethodActions(serviceImplClass).isEmpty()
&& (serviceImplClass.getAnnotation(Priority.class) == null && serviceImplClass.getAnnotation(javax.annotation.Priority.class) == null)) { //class没有可用的方法且没有标记启动优先级的 通常为BaseService
if (!serviceImplClass.getName().startsWith("org.redkale.") && !serviceImplClass.getSimpleName().contains("Base")) {
logger.log(Level.FINE, serviceImplClass + " cannot load because not found less one public non-final method");

View File

@@ -57,10 +57,18 @@ public abstract class Sncp {
private Sncp() {
}
public static Uint128 actionid(final RpcAction action) {
return hash(action.name());
}
public static Uint128 actionid(final java.lang.reflect.Method method) {
if (method == null) {
return Uint128.ZERO;
}
RpcAction action = method.getAnnotation(RpcAction.class);
if (action != null) {
return hash(action.name());
}
StringBuilder sb = new StringBuilder(); //不能使用method.toString() 因为包含declaringClass信息导致接口与实现类的方法hash不一致
sb.append(method.getReturnType().getName()).append(' ');
sb.append(method.getName());

View File

@@ -87,8 +87,8 @@ public final class SncpClient {
this.serviceid = Sncp.serviceid(serviceResourceName, serviceResourceType);
final List<SncpAction> methodens = new ArrayList<>();
//------------------------------------------------------------------------------
for (java.lang.reflect.Method method : parseMethod(serviceClass)) {
methodens.add(new SncpAction(serviceClass, method, Sncp.actionid(method)));
for (Map.Entry<Uint128, Method> en : parseMethodActions(serviceClass).entrySet()) {
methodens.add(new SncpAction(serviceClass, en.getValue(), en.getKey()));
}
this.actions = methodens.toArray(new SncpAction[methodens.size()]);
this.addrBytes = clientSncpAddress == null ? new byte[4] : clientSncpAddress.getAddress().getAddress();
@@ -101,8 +101,8 @@ public final class SncpClient {
static List<SncpAction> getSncpActions(final Class serviceClass) {
final List<SncpAction> actions = new ArrayList<>();
//------------------------------------------------------------------------------
for (java.lang.reflect.Method method : parseMethod(serviceClass)) {
actions.add(new SncpAction(serviceClass, method, Sncp.actionid(method)));
for (Map.Entry<Uint128, Method> en : parseMethodActions(serviceClass).entrySet()) {
actions.add(new SncpAction(serviceClass, en.getValue(), en.getKey()));
}
return actions;
}
@@ -170,10 +170,10 @@ public final class SncpClient {
+ ", actions.size = " + actions.length + ")";
}
public static List<Method> parseMethod(final Class serviceClass) {
public static LinkedHashMap<Uint128, Method> parseMethodActions(final Class serviceClass) {
final List<Method> list = new ArrayList<>();
final List<Method> multis = new ArrayList<>();
final Map<Uint128, Method> actionids = new HashMap<>();
final Map<Uint128, Method> actionids = new LinkedHashMap<>();
for (final java.lang.reflect.Method method : serviceClass.getMethods()) {
if (method.isSynthetic()) {
continue;
@@ -201,7 +201,6 @@ public final class SncpClient {
continue;
}
}
//if (onlySncpDyn && method.getAnnotation(SncpDyn.class) == null) continue;
Uint128 actionid = Sncp.actionid(method);
Method old = actionids.get(actionid);
@@ -230,7 +229,16 @@ public final class SncpClient {
});
//带SncpDyn必须排在前面
multis.addAll(list);
return multis;
final LinkedHashMap<Uint128, Method> rs = new LinkedHashMap<>();
for (Method method : multis) {
for (Map.Entry<Uint128, Method> en : actionids.entrySet()) {
if (en.getValue() == method) {
rs.put(en.getKey(), en.getValue());
break;
}
}
}
return rs;
}
//只给远程模式调用的
@@ -597,18 +605,6 @@ public final class SncpClient {
tpoicAddrIndex = i;
}
}
for (Annotation ann : anns[i]) {
if (ann.annotationType() == RpcCall.class) {
try {
atts[i + 1] = ((RpcCall) ann).value().getDeclaredConstructor().newInstance();
RedkaleClassLoader.putReflectionDeclaredConstructors(((RpcCall) ann).value(), ((RpcCall) ann).value().getName());
hasattr = true;
} catch (Exception e) {
logger.log(Level.SEVERE, RpcCall.class.getSimpleName() + ".attribute cannot a newInstance for" + method, e);
}
break;
}
}
}
}
}

View File

@@ -6,7 +6,6 @@
package org.redkale.net.sncp;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.nio.channels.CompletionHandler;
import java.util.*;
@@ -21,7 +20,7 @@ import org.redkale.asm.Type;
import org.redkale.convert.bson.*;
import org.redkale.net.sncp.SncpAsyncHandler.DefaultSncpAsyncHandler;
import static org.redkale.net.sncp.SncpRequest.DEFAULT_HEADER;
import org.redkale.service.*;
import org.redkale.service.Service;
import org.redkale.util.*;
/**
@@ -49,49 +48,16 @@ public final class SncpDynServlet extends SncpServlet {
this.maxTypeLength = maxTypeLength;
this.maxNameLength = maxNameLength;
this.serviceid = Sncp.serviceid(serviceResourceName, serviceResourceType);
Set<Uint128> actionids = new HashSet<>();
RedkaleClassLoader.putReflectionPublicMethods(service.getClass().getName());
for (java.lang.reflect.Method method : service.getClass().getMethods()) {
if (method.isSynthetic()) {
continue;
}
if (Modifier.isStatic(method.getModifiers())) {
continue;
}
if (Modifier.isFinal(method.getModifiers())) {
continue;
}
if (method.getAnnotation(Local.class) != null) {
continue;
}
if (method.getName().equals("getClass") || method.getName().equals("toString")) {
continue;
}
if (method.getName().equals("equals") || method.getName().equals("hashCode")) {
continue;
}
if (method.getName().equals("notify") || method.getName().equals("notifyAll") || method.getName().equals("wait")) {
continue;
}
if (method.getParameterCount() == 1 && method.getParameterTypes()[0] == AnyValue.class) {
if (method.getName().equals("init") || method.getName().equals("stop") || method.getName().equals("destroy")) {
continue;
}
}
final Uint128 actionid = Sncp.actionid(method);
for (Map.Entry<Uint128, Method> en : SncpClient.parseMethodActions(service.getClass()).entrySet()) {
SncpServletAction action;
try {
action = SncpServletAction.create(service, actionid, method);
action = SncpServletAction.create(service, en.getKey(), en.getValue());
} catch (RuntimeException e) {
throw new SncpException(method + " create " + SncpServletAction.class.getSimpleName() + " error", e);
throw new SncpException(en.getValue() + " create " + SncpServletAction.class.getSimpleName() + " error", e);
}
action.convert = convert;
if (actionids.contains(actionid)) {
throw new SncpException(type.getName() + " have action(Method=" + method + ", actionid=" + actionid + ") same to (" + actions.get(actionid).method + ")");
}
actions.put(actionid, action);
actionids.add(actionid);
actions.put(en.getKey(), action);
}
maxNameLength.set(Math.max(maxNameLength.get(), serviceResourceName.length() + 1));
maxTypeLength.set(Math.max(maxTypeLength.get(), type.getName().length()));
@@ -662,29 +628,6 @@ public final class SncpDynServlet extends SncpServlet {
instance.handlerFuncParamIndex = handlerFuncIndex;
instance.handlerFuncParamClass = handlerFuncClass;
instance.boolReturnTypeFuture = boolReturnTypeFuture;
org.redkale.util.Attribute[] atts = new org.redkale.util.Attribute[originalParamTypes.length + 1];
Annotation[][] anns = method.getParameterAnnotations();
boolean hasattr = false;
for (int i = 0; i < anns.length; i++) {
if (anns[i].length > 0) {
for (Annotation ann : anns[i]) {
if (ann.annotationType() == RpcCall.class) {
try {
atts[i + 1] = ((RpcCall) ann).value().getDeclaredConstructor().newInstance();
RedkaleClassLoader.putReflectionDeclaredConstructors(((RpcCall) ann).value(), ((RpcCall) ann).value().getName());
hasattr = true;
} catch (Exception e) {
logger.log(Level.SEVERE, RpcCall.class.getSimpleName() + ".attribute cannot a newInstance for" + method, e);
}
break;
}
}
}
}
if (hasattr) {
instance.paramAttrs = atts;
}
newClazz.getField("service").set(instance, service);
return instance;
} catch (Exception ex) {

View File

@@ -0,0 +1,26 @@
/*
*
*/
package org.redkale.service;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.*;
/**
* 用于自定义SncpActionid默认会根据Method.toString来计算actionid
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
* @since 2.8.0
*/
@Inherited
@Documented
@Target({METHOD})
@Retention(RUNTIME)
public @interface RpcAction {
String name();
}

View File

@@ -1,25 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.service;
import java.lang.annotation.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import org.redkale.util.*;
/**
* 参数回写, 当Service的方法需要更改参数对象内部的数据时需要使用RpcCall
*
* <p> 详情见: https://redkale.org
* @author zhangjx
*/
@Inherited
@Documented
@Target({ElementType.PARAMETER})
@Retention(RUNTIME)
public @interface RpcCall {
Class<? extends Attribute> value();
}

View File

@@ -1,67 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.service;
import java.io.Serializable;
import java.lang.reflect.Array;
import org.redkale.util.Attribute;
/**
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
* @param <T> 对象类型
* @param <F> 字段类型
*/
@SuppressWarnings("unchecked")
public class RpcCallArrayAttribute<T, F> implements Attribute<T[], F> {
public static final RpcCallArrayAttribute instance = new RpcCallArrayAttribute();
@Override
public Class<? extends F> type() {
return (Class<F>) Object.class;
}
@Override
public Class<T[]> declaringClass() {
return (Class<T[]>) (Class) Object[].class;
}
@Override
public String field() {
return "";
}
@Override
public F get(final T[] objs) {
if (objs == null || objs.length == 0) {
return null;
}
final Attribute<T, Serializable> attr = RpcCallAttribute.load(objs[0].getClass());
final Object keys = Array.newInstance(attr.type(), objs.length);
for (int i = 0; i < objs.length; i++) {
Array.set(keys, i, attr.get(objs[i]));
}
return (F) keys;
}
@Override
public void set(final T[] objs, final F keys) {
if (objs == null || objs.length == 0) {
return;
}
final Attribute<T, Serializable> attr = RpcCallAttribute.load(objs[0].getClass());
for (int i = 0; i < objs.length; i++) {
attr.set(objs[i], (Serializable) Array.get(keys, i));
}
}
}

View File

@@ -1,83 +0,0 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.redkale.service;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.concurrent.ConcurrentHashMap;
import org.redkale.util.Attribute;
/**
*
* <p>
* 详情见: https://redkale.org
*
* @author zhangjx
*
* @since 2.1.0
*/
public class RpcCallAttribute implements Attribute<Object, Serializable> {
public static final RpcCallAttribute instance = new RpcCallAttribute();
private static final ConcurrentHashMap<Class, Attribute> attributes = new ConcurrentHashMap<>();
static <T> Attribute<T, Serializable> load(final Class clazz) {
Attribute rs = attributes.get(clazz);
if (rs != null) {
return rs;
}
synchronized (attributes) {
rs = attributes.get(clazz);
if (rs == null) {
Class cltmp = clazz;
do {
for (Field field : cltmp.getDeclaredFields()) {
try {
rs = Attribute.create(cltmp, field);
attributes.put(clazz, rs);
return rs;
} catch (RuntimeException e) {
}
}
} while ((cltmp = cltmp.getSuperclass()) != Object.class);
}
return rs;
}
}
@Override
public Class<Serializable> type() {
return Serializable.class;
}
@Override
public Class<Object> declaringClass() {
return Object.class;
}
@Override
public String field() {
return "";
}
@Override
public Serializable get(final Object obj) {
if (obj == null) {
return null;
}
return load(obj.getClass()).get(obj);
}
@Override
public void set(final Object obj, final Serializable key) {
if (obj == null) {
return;
}
load(obj.getClass()).set(obj, key);
}
}

View File

@@ -6,7 +6,7 @@
package org.redkale.test.sncp;
import java.util.concurrent.CompletableFuture;
import org.redkale.service.*;
import org.redkale.service.Service;
/**
*
@@ -22,7 +22,7 @@ public interface SncpTestIService extends Service {
public CompletableFuture<String> queryResultAsync(SncpTestBean bean);
public void insert(@RpcCall(RpcCallArrayAttribute.class) SncpTestBean... beans);
public void insert(SncpTestBean... beans);
public String updateBean(@RpcCall(SncpTestServiceImpl.CallAttribute.class) SncpTestBean bean);
public String updateBean(SncpTestBean bean);
}

View File

@@ -8,8 +8,7 @@ package org.redkale.test.sncp;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.nio.channels.CompletionHandler;
import java.util.concurrent.*;
import java.util.concurrent.CompletableFuture;
import org.redkale.annotation.ResourceType;
import org.redkale.net.*;
import org.redkale.net.sncp.*;
@@ -84,7 +83,7 @@ public class SncpTestServiceImpl implements SncpTestIService {
}
@Override
public void insert(@RpcCall(RpcCallArrayAttribute.class) SncpTestBean... beans) {
public void insert(SncpTestBean... beans) {
for (SncpTestBean bean : beans) {
bean.setId(System.currentTimeMillis());
}
@@ -98,11 +97,13 @@ public class SncpTestServiceImpl implements SncpTestIService {
public void queryResult(CompletionHandler<String, SncpTestBean> handler, @RpcAttachment SncpTestBean bean) {
System.out.println(Thread.currentThread().getName() + " handler 运行了queryResult方法");
if (handler != null) handler.completed("result: " + bean, bean);
if (handler != null) {
handler.completed("result: " + bean, bean);
}
}
@Override
public String updateBean(@RpcCall(CallAttribute.class) SncpTestBean bean) {
public String updateBean(SncpTestBean bean) {
bean.setId(System.currentTimeMillis());
System.out.println(Thread.currentThread().getName() + " 运行了updateBean方法");
return "result: " + bean;
@@ -120,7 +121,7 @@ public class SncpTestServiceImpl implements SncpTestIService {
System.out.println(method);
}
System.out.println("-----------------------------------");
for (Method method : SncpClient.parseMethod(service.getClass())) {
for (Method method : SncpClient.parseMethodActions(service.getClass()).values()) {
System.out.println(method);
}
System.out.println("-----------------------------------");
@@ -129,7 +130,7 @@ public class SncpTestServiceImpl implements SncpTestIService {
System.out.println(method);
}
System.out.println("-----------------------------------");
for (Method method : SncpClient.parseMethod(service.getClass())) {
for (Method method : SncpClient.parseMethodActions(service.getClass()).values()) {
System.out.println(method);
}
System.out.println("-----------------------------------");
@@ -138,7 +139,7 @@ public class SncpTestServiceImpl implements SncpTestIService {
System.out.println(method);
}
System.out.println("-----------------------------------");
for (Method method : SncpClient.parseMethod(service.getClass())) {
for (Method method : SncpClient.parseMethodActions(service.getClass()).values()) {
System.out.println(method);
}
System.out.println("-----------------------------------");