【不兼容】移除RpcCall、RpcCallAttribute功能
This commit is contained in:
@@ -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");
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
26
src/main/java/org/redkale/service/RpcAction.java
Normal file
26
src/main/java/org/redkale/service/RpcAction.java
Normal 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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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("-----------------------------------");
|
||||
|
||||
Reference in New Issue
Block a user