This commit is contained in:
redkale
2024-10-11 00:46:23 +08:00
parent 8ea63c5171
commit 335933a0f4
11 changed files with 410 additions and 295 deletions

View File

@@ -53,13 +53,13 @@ public abstract class SncpActionServlet extends SncpServlet {
protected final Class<? extends CompletionHandler> paramHandlerClass; // CompletionHandler参数的类型 protected final Class<? extends CompletionHandler> paramHandlerClass; // CompletionHandler参数的类型
protected final java.lang.reflect.Type paramHandlerResultType; // CompletionHandler.completed第一个参数的类型 protected final java.lang.reflect.Type paramHandlerType; // CompletionHandler.completed第一个参数的类型
@ClassDepends @ClassDepends
protected final java.lang.reflect.Type returnObjectType; // 返回结果类型 void必须设为null protected final java.lang.reflect.Type returnObjectType; // 返回结果类型 void必须设为null
@ClassDepends @ClassDepends
protected final java.lang.reflect.Type returnFutureResultType; // 返回结果的CompletableFuture的结果泛型类型 protected final java.lang.reflect.Type returnFutureType; // 返回结果的CompletableFuture的结果泛型类型
@ClassDepends @ClassDepends
protected SncpActionServlet( protected SncpActionServlet(
@@ -119,7 +119,7 @@ public abstract class SncpActionServlet extends SncpServlet {
this.paramTypes = types; this.paramTypes = types;
this.paramHandlerIndex = handlerFuncIndex; this.paramHandlerIndex = handlerFuncIndex;
this.paramHandlerClass = handlerFuncClass; this.paramHandlerClass = handlerFuncClass;
this.paramHandlerResultType = handlerResultType; this.paramHandlerType = handlerResultType;
this.returnObjectType = this.returnObjectType =
originalReturnType == void.class || originalReturnType == Void.class ? null : originalReturnType; originalReturnType == void.class || originalReturnType == Void.class ? null : originalReturnType;
if (Future.class.isAssignableFrom(method.getReturnType())) { if (Future.class.isAssignableFrom(method.getReturnType())) {
@@ -134,9 +134,9 @@ public abstract class SncpActionServlet extends SncpServlet {
} else { } else {
throw new SncpException(service.getClass() + " had unknown return genericType in " + method); throw new SncpException(service.getClass() + " had unknown return genericType in " + method);
} }
this.returnFutureResultType = returnType; this.returnFutureType = returnType;
} else { } else {
this.returnFutureResultType = null; this.returnFutureType = null;
} }
NonBlocking non = method.getAnnotation(NonBlocking.class); NonBlocking non = method.getAnnotation(NonBlocking.class);
if (non == null) { if (non == null) {
@@ -150,7 +150,7 @@ public abstract class SncpActionServlet extends SncpServlet {
@Override @Override
public final void execute(SncpRequest request, SncpResponse response) throws IOException { public final void execute(SncpRequest request, SncpResponse response) throws IOException {
if (paramHandlerIndex > 0) { if (paramHandlerIndex > 0) {
response.paramAsyncHandler(paramHandlerClass, paramHandlerResultType); response.paramAsyncHandler(paramHandlerClass, paramHandlerType);
} }
try { try {
action(request, response); action(request, response);
@@ -194,7 +194,7 @@ public abstract class SncpActionServlet extends SncpServlet {
* *
* public void update(long show, short v2, CompletionHandler&#60;Boolean, TestBean&#62; handler, TestBean bean, String name, int id); * public void update(long show, short v2, CompletionHandler&#60;Boolean, TestBean&#62; handler, TestBean bean, String name, int id);
* *
* public CompletableFuture&#60;String&#62; changeName(TestBean bean, String name, int id); * public CompletableFuture&#60;String&#62; changeName(TestBean bean, String name, int id);
* *
* } * }
* *
@@ -304,14 +304,14 @@ public abstract class SncpActionServlet extends SncpServlet {
* &#064;Override * &#064;Override
* public void action(SncpRequest request, SncpResponse response) throws Throwable { * public void action(SncpRequest request, SncpResponse response) throws Throwable {
* Convert&#60;Reader, Writer&#62; convert = request.getConvert(); * Convert&#60;Reader, Writer&#62; convert = request.getConvert();
* Reader in = request.getReader(); * Reader in = request.getReader();
* TestBean arg1 = convert.convertFrom(paramTypes[1], in); * TestBean arg1 = convert.convertFrom(paramTypes[1], in);
* String arg2 = convert.convertFrom(paramTypes[2], in); * String arg2 = convert.convertFrom(paramTypes[2], in);
* int arg3 = convert.convertFrom(paramTypes[3], in); * int arg3 = convert.convertFrom(paramTypes[3], in);
* TestService serviceObj = (TestService) service(); * TestService serviceObj = (TestService) service();
* CompletableFuture future = serviceObj.changeName(arg1, arg2, arg3); * CompletableFuture future = serviceObj.changeName(arg1, arg2, arg3);
* response.finishFuture(paramHandlerResultType, future); * response.finishFuture(paramHandlerType, future);
* } * }
* } * }
* *
* </pre> * </pre>
@@ -349,6 +349,9 @@ public abstract class SncpActionServlet extends SncpServlet {
final String requestDesc = Type.getDescriptor(SncpRequest.class); final String requestDesc = Type.getDescriptor(SncpRequest.class);
final String responseDesc = Type.getDescriptor(SncpResponse.class); final String responseDesc = Type.getDescriptor(SncpResponse.class);
final String serviceDesc = Type.getDescriptor(Service.class); final String serviceDesc = Type.getDescriptor(Service.class);
final String handlerDesc = Type.getDescriptor(CompletionHandler.class);
final String futureDesc = Type.getDescriptor(Future.class);
final String reflectTypeDesc = Type.getDescriptor(java.lang.reflect.Type.class);
final boolean boolReturnTypeFuture = Future.class.isAssignableFrom(method.getReturnType()); final boolean boolReturnTypeFuture = Future.class.isAssignableFrom(method.getReturnType());
final String newDynName = "org/redkaledyn/sncp/servlet/action/_DynSncpActionServlet__" final String newDynName = "org/redkaledyn/sncp/servlet/action/_DynSncpActionServlet__"
+ resourceType.getSimpleName() + "_" + method.getName() + "_" + actionid; + resourceType.getSimpleName() + "_" + method.getName() + "_" + actionid;
@@ -368,6 +371,27 @@ public abstract class SncpActionServlet extends SncpServlet {
final java.lang.reflect.Type originalReturnType = final java.lang.reflect.Type originalReturnType =
TypeToken.getGenericType(method.getGenericReturnType(), serviceClass); TypeToken.getGenericType(method.getGenericReturnType(), serviceClass);
final Class[] paramClasses = method.getParameterTypes();
java.lang.reflect.Type paramComposeBeanType0 = SncpRemoteAction.createParamComposeBeanType(
serviceImplClass, method, actionid, originalParamTypes, paramClasses);
if (paramComposeBeanType0 != null && paramComposeBeanType0 == originalParamTypes[0]) {
paramComposeBeanType0 = null;
}
int handlerFuncIndex = -1;
for (int i = 0; i < paramClasses.length; i++) { // 反序列化方法的每个参数
if (CompletionHandler.class.isAssignableFrom(paramClasses[i])) {
if (boolReturnTypeFuture) {
throw new SncpException(method + " have both CompletionHandler and CompletableFuture");
}
if (handlerFuncIndex >= 0) {
throw new SncpException(method + " have more than one CompletionHandler type parameter");
}
Sncp.checkAsyncModifier(paramClasses[i], method);
handlerFuncIndex = i;
}
}
final java.lang.reflect.Type paramComposeBeanType = paramComposeBeanType0;
if (newClazz == null) { if (newClazz == null) {
// ------------------------------------------------------------- // -------------------------------------------------------------
ClassWriter cw = new ClassWriter(COMPUTE_FRAMES); ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
@@ -434,107 +458,193 @@ public abstract class SncpActionServlet extends SncpServlet {
mv.visitMethodInsn(INVOKEVIRTUAL, requestName, "getReader", "()" + readerDesc, false); mv.visitMethodInsn(INVOKEVIRTUAL, requestName, "getReader", "()" + readerDesc, false);
mv.visitVarInsn(ASTORE, 4); mv.visitVarInsn(ASTORE, 4);
} }
int iconst = ICONST_1; if (paramComposeBeanType == null) {
int intconst = 1; int iconst = ICONST_1;
int store = 5; // action的参数个数+2 int intconst = 1;
final Class[] paramClasses = method.getParameterTypes(); int store = 5; // action的参数个数+2
int[][] codes = new int[paramClasses.length][2]; int[][] codes = new int[paramClasses.length][2];
int handlerFuncIndex = -1; for (int i = 0; i < paramClasses.length; i++) { // 反序列化方法的每个参数
for (int i = 0; i < paramClasses.length; i++) { // 反序列化方法的每个参数 if (CompletionHandler.class.isAssignableFrom(paramClasses[i])) {
if (CompletionHandler.class.isAssignableFrom(paramClasses[i])) { mv.visitVarInsn(ALOAD, 2);
if (boolReturnTypeFuture) { mv.visitMethodInsn(
throw new SncpException(method + " have both CompletionHandler and CompletableFuture"); INVOKEVIRTUAL,
responseName,
"getParamAsyncHandler",
"()Ljava/nio/channels/CompletionHandler;",
false);
mv.visitTypeInsn(
CHECKCAST, paramClasses[i].getName().replace('.', '/'));
mv.visitVarInsn(ASTORE, store);
codes[i] = new int[] {ALOAD, store};
store++;
iconst++;
intconst++;
mv.visitVarInsn(ALOAD, 3);
mv.visitLdcInsn(Type.getType(Type.getDescriptor(CompletionHandler.class)));
mv.visitVarInsn(ALOAD, 4);
mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false);
mv.visitInsn(POP);
continue;
} }
if (handlerFuncIndex >= 0) { mv.visitVarInsn(ALOAD, 3);
throw new SncpException(method + " have more than one CompletionHandler type parameter"); mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, "paramTypes", "[Ljava/lang/reflect/Type;");
if (intconst < 6) {
mv.visitInsn(ICONST_0 + intconst);
} else if (iconst <= Byte.MAX_VALUE) {
mv.visitIntInsn(BIPUSH, intconst);
} else if (iconst <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, intconst);
} else {
mv.visitLdcInsn(intconst);
} }
Sncp.checkAsyncModifier(paramClasses[i], method); mv.visitInsn(AALOAD);
handlerFuncIndex = i; mv.visitVarInsn(ALOAD, 4);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn( mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false);
INVOKEVIRTUAL, int load = ALOAD;
responseName, int v = 0;
"getParamAsyncHandler", if (paramClasses[i].isPrimitive()) {
"()Ljava/nio/channels/CompletionHandler;", int storecode = ISTORE;
false); load = ILOAD;
mv.visitTypeInsn(CHECKCAST, paramClasses[i].getName().replace('.', '/')); if (paramClasses[i] == long.class) {
mv.visitVarInsn(ASTORE, store); storecode = LSTORE;
codes[i] = new int[] {ALOAD, store}; load = LLOAD;
store++; v = 1;
} else if (paramClasses[i] == float.class) {
storecode = FSTORE;
load = FLOAD;
v = 1;
} else if (paramClasses[i] == double.class) {
storecode = DSTORE;
load = DLOAD;
v = 1;
}
Class bigPrimitiveClass = TypeToken.primitiveToWrapper(paramClasses[i]);
String bigPrimitiveName =
bigPrimitiveClass.getName().replace('.', '/');
try {
Method pm = bigPrimitiveClass.getMethod(paramClasses[i].getSimpleName() + "Value");
mv.visitTypeInsn(CHECKCAST, bigPrimitiveName);
mv.visitMethodInsn(
INVOKEVIRTUAL,
bigPrimitiveName,
pm.getName(),
Type.getMethodDescriptor(pm),
false);
} catch (Exception ex) {
throw new SncpException(ex); // 不可能会发生
}
mv.visitVarInsn(storecode, store);
} else {
mv.visitTypeInsn(
CHECKCAST, paramClasses[i].getName().replace('.', '/'));
mv.visitVarInsn(ASTORE, store); //
}
codes[i] = new int[] {load, store};
store += v;
iconst++; iconst++;
intconst++; intconst++;
mv.visitVarInsn(ALOAD, 3); store++;
mv.visitLdcInsn(Type.getType(Type.getDescriptor(CompletionHandler.class)));
mv.visitVarInsn(ALOAD, 4);
mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false);
mv.visitInsn(POP);
continue;
} }
mv.visitVarInsn(ALOAD, 3); { // 调用service
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, "paramTypes", "[Ljava/lang/reflect/Type;"); mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "service", "()" + serviceDesc, false);
mv.visitTypeInsn(CHECKCAST, serviceImpTypeName);
mv.visitVarInsn(ASTORE, store);
if (intconst < 6) { mv.visitVarInsn(ALOAD, store);
mv.visitInsn(ICONST_0 + intconst); for (int[] j : codes) {
} else if (iconst <= Byte.MAX_VALUE) { mv.visitVarInsn(j[0], j[1]);
mv.visitIntInsn(BIPUSH, intconst);
} else if (iconst <= Short.MAX_VALUE) {
mv.visitIntInsn(SIPUSH, intconst);
} else {
mv.visitLdcInsn(intconst);
}
mv.visitInsn(AALOAD);
mv.visitVarInsn(ALOAD, 4);
mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false);
int load = ALOAD;
int v = 0;
if (paramClasses[i].isPrimitive()) {
int storecode = ISTORE;
load = ILOAD;
if (paramClasses[i] == long.class) {
storecode = LSTORE;
load = LLOAD;
v = 1;
} else if (paramClasses[i] == float.class) {
storecode = FSTORE;
load = FLOAD;
v = 1;
} else if (paramClasses[i] == double.class) {
storecode = DSTORE;
load = DLOAD;
v = 1;
} }
Class bigPrimitiveClass = TypeToken.primitiveToWrapper(paramClasses[i]); mv.visitMethodInsn(
String bigPrimitiveName = bigPrimitiveClass.getName().replace('.', '/'); serviceImplClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL,
try { serviceImpTypeName,
Method pm = bigPrimitiveClass.getMethod(paramClasses[i].getSimpleName() + "Value"); method.getName(),
mv.visitTypeInsn(CHECKCAST, bigPrimitiveName); Type.getMethodDescriptor(method),
serviceImplClass.isInterface());
store++;
}
if (method.getReturnType() != void.class) {
final Class returnClass = method.getReturnType();
if (returnClass.isPrimitive()) {
Class bigClass = TypeToken.primitiveToWrapper(returnClass);
try {
Method vo = bigClass.getMethod("valueOf", returnClass);
mv.visitMethodInsn(
INVOKESTATIC,
bigClass.getName().replace('.', '/'),
vo.getName(),
Type.getMethodDescriptor(vo),
false);
} catch (Exception ex) {
throw new SncpException(ex); // 不可能会发生
}
}
mv.visitVarInsn(ASTORE, store); // 11
if (boolReturnTypeFuture) { // 返回类型为Future
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, "returnFutureType", reflectTypeDesc);
mv.visitVarInsn(ALOAD, store);
mv.visitMethodInsn( mv.visitMethodInsn(
INVOKEVIRTUAL, bigPrimitiveName, pm.getName(), Type.getMethodDescriptor(pm), false); INVOKEVIRTUAL,
} catch (Exception ex) { responseName,
throw new SncpException(ex); // 不可能会发生 "finishFuture",
"(" + reflectTypeDesc + futureDesc + ")V",
false);
} else if (handlerFuncIndex >= 0) { // 参数有CompletionHandler
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, responseName, "finishVoid", "()V", false);
} else { // 普通对象
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, "returnObjectType", reflectTypeDesc);
mv.visitVarInsn(ALOAD, store);
mv.visitMethodInsn(
INVOKEVIRTUAL,
responseName,
"finish",
"(" + reflectTypeDesc + "Ljava/lang/Object;)V",
false);
} }
mv.visitVarInsn(storecode, store); } else { // void返回类型
} else { mv.visitVarInsn(ALOAD, 2);
mv.visitTypeInsn(CHECKCAST, paramClasses[i].getName().replace('.', '/')); mv.visitMethodInsn(INVOKEVIRTUAL, responseName, "finishVoid", "()V", false);
mv.visitVarInsn(ASTORE, store); //
} }
codes[i] = new int[] {load, store}; } else { // 动态生成的参数组合类
store += v; Class paramComposeBeanClass = TypeToken.typeToClass(paramComposeBeanType);
iconst++; String paramComposeBeanName =
intconst++; paramComposeBeanClass.getName().replace('.', '/');
store++; mv.visitVarInsn(ALOAD, 3); // convert
} mv.visitVarInsn(ALOAD, 0);
{ // 调用service mv.visitFieldInsn(GETFIELD, newDynName, "paramComposeType", reflectTypeDesc);
mv.visitVarInsn(ALOAD, 4); // reader
mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false);
mv.visitTypeInsn(CHECKCAST, paramComposeBeanName);
mv.visitVarInsn(ASTORE, 5); // paramBean
// 给CompletionHandler参数赋值
mv.visitVarInsn(ALOAD, 5);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, responseName, "getParamAsyncHandler", "()" + handlerDesc, false);
mv.visitFieldInsn(PUTFIELD, paramComposeBeanName, "arg3", handlerDesc);
// 调用service()
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "service", "()" + serviceDesc, false); mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "service", "()" + serviceDesc, false);
mv.visitTypeInsn(CHECKCAST, serviceImpTypeName); mv.visitTypeInsn(CHECKCAST, serviceImpTypeName);
mv.visitVarInsn(ASTORE, store); mv.visitVarInsn(ASTORE, 6); // service
mv.visitVarInsn(ALOAD, store); // 执行service方法
for (int[] j : codes) { mv.visitVarInsn(ALOAD, 6); // service
mv.visitVarInsn(j[0], j[1]); for (int i = 1; i <= paramClasses.length; i++) {
mv.visitVarInsn(ALOAD, 5); // paramBean
mv.visitFieldInsn(
GETFIELD, paramComposeBeanName, "arg" + i, Type.getDescriptor(paramClasses[i - 1]));
} }
mv.visitMethodInsn( mv.visitMethodInsn(
serviceImplClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, serviceImplClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL,
@@ -542,58 +652,60 @@ public abstract class SncpActionServlet extends SncpServlet {
method.getName(), method.getName(),
Type.getMethodDescriptor(method), Type.getMethodDescriptor(method),
serviceImplClass.isInterface()); serviceImplClass.isInterface());
store++;
}
if (method.getReturnType() != void.class) {
final Class returnClass = method.getReturnType();
if (returnClass.isPrimitive()) {
Class bigClass = TypeToken.primitiveToWrapper(returnClass);
try {
Method vo = bigClass.getMethod("valueOf", returnClass);
mv.visitMethodInsn(
INVOKESTATIC,
bigClass.getName().replace('.', '/'),
vo.getName(),
Type.getMethodDescriptor(vo),
false);
} catch (Exception ex) {
throw new SncpException(ex); // 不可能会发生
}
}
mv.visitVarInsn(ASTORE, store); // 11
if (boolReturnTypeFuture) { // 返回类型为Future // 返回
mv.visitVarInsn(ALOAD, 2); if (method.getReturnType() != void.class) {
mv.visitVarInsn(ALOAD, 0); final Class returnClass = method.getReturnType();
mv.visitFieldInsn(GETFIELD, newDynName, "returnFutureResultType", "Ljava/lang/reflect/Type;"); if (returnClass.isPrimitive()) {
mv.visitVarInsn(ALOAD, store); Class bigClass = TypeToken.primitiveToWrapper(returnClass);
mv.visitMethodInsn( try {
INVOKEVIRTUAL, Method vo = bigClass.getMethod("valueOf", returnClass);
responseName, mv.visitMethodInsn(
"finishFuture", INVOKESTATIC,
"(Ljava/lang/reflect/Type;Ljava/util/concurrent/Future;)V", bigClass.getName().replace('.', '/'),
false); vo.getName(),
} else if (handlerFuncIndex >= 0) { // 参数有CompletionHandler Type.getMethodDescriptor(vo),
mv.visitVarInsn(ALOAD, 2); false);
} catch (Exception ex) {
throw new SncpException(ex); // 不可能会发生
}
}
mv.visitVarInsn(ASTORE, 7); // returnObject
if (boolReturnTypeFuture) { // 返回类型为Future
mv.visitVarInsn(ALOAD, 2); // response
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, "returnFutureType", reflectTypeDesc);
mv.visitVarInsn(ALOAD, 7); // returnObject
mv.visitMethodInsn(
INVOKEVIRTUAL,
responseName,
"finishFuture",
"(" + reflectTypeDesc + futureDesc + ")V",
false);
} else if (handlerFuncIndex >= 0) { // 参数有CompletionHandler
mv.visitVarInsn(ALOAD, 2); // response
mv.visitMethodInsn(INVOKEVIRTUAL, responseName, "finishVoid", "()V", false);
} else { // 普通对象
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, "returnObjectType", reflectTypeDesc);
mv.visitVarInsn(ALOAD, 7); // returnObject
mv.visitMethodInsn(
INVOKEVIRTUAL,
responseName,
"finish",
"(" + reflectTypeDesc + "Ljava/lang/Object;)V",
false);
}
} else { // void返回类型
mv.visitVarInsn(ALOAD, 2); // response
mv.visitMethodInsn(INVOKEVIRTUAL, responseName, "finishVoid", "()V", false); mv.visitMethodInsn(INVOKEVIRTUAL, responseName, "finishVoid", "()V", false);
} else { // 普通对象
mv.visitVarInsn(ALOAD, 2);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, newDynName, "returnObjectType", "Ljava/lang/reflect/Type;");
mv.visitVarInsn(ALOAD, store);
mv.visitMethodInsn(
INVOKEVIRTUAL,
responseName,
"finish",
"(Ljava/lang/reflect/Type;Ljava/lang/Object;)V",
false);
} }
} else { // void返回类型
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, responseName, "finishVoid", "()V", false);
} }
mv.visitInsn(RETURN); mv.visitInsn(RETURN);
mv.visitMaxs(8, store); mv.visitMaxs(8, 8);
mv.visitEnd(); mv.visitEnd();
} }
cw.visitEnd(); cw.visitEnd();

View File

@@ -60,6 +60,9 @@ public final class SncpRemoteAction {
// 参数数量为0: 值为null; 参数数量为1且参数类型为JavaBean: 值为第一个参数的类型; 其他情况: 动态生成的Object类 // 参数数量为0: 值为null; 参数数量为1且参数类型为JavaBean: 值为第一个参数的类型; 其他情况: 动态生成的Object类
protected final Type paramComposeBeanType; protected final Type paramComposeBeanType;
// 只有paramComposeBeanType为动态生成的组合类时才有值;
protected final Creator paramComposeBeanCreator;
protected final int paramHandlerIndex; protected final int paramHandlerIndex;
protected final int paramHandlerAttachIndex; protected final int paramHandlerAttachIndex;
@@ -72,9 +75,9 @@ public final class SncpRemoteAction {
protected final Class<? extends CompletionHandler> paramHandlerClass; // CompletionHandler参数的类型 protected final Class<? extends CompletionHandler> paramHandlerClass; // CompletionHandler参数的类型
protected final java.lang.reflect.Type paramHandlerResultType; // CompletionHandler.completed第一个参数的类型 protected final java.lang.reflect.Type paramHandlerType; // CompletionHandler.completed第一个参数的类型
protected final java.lang.reflect.Type returnFutureResultType; // 返回结果的CompletableFuture的结果泛型类型 protected final java.lang.reflect.Type returnFutureType; // 返回结果的CompletableFuture的结果泛型类型
protected final Class<? extends Future> returnFutureClass; // 返回结果的CompletableFuture类型 protected final Class<? extends Future> returnFutureClass; // 返回结果的CompletableFuture类型
@@ -95,8 +98,10 @@ public final class SncpRemoteAction {
this.returnObjectType = rt == void.class || rt == Void.class ? null : rt; this.returnObjectType = rt == void.class || rt == Void.class ? null : rt;
this.paramTypes = TypeToken.getGenericType(method.getGenericParameterTypes(), serviceImplClass); this.paramTypes = TypeToken.getGenericType(method.getGenericParameterTypes(), serviceImplClass);
this.paramClasses = method.getParameterTypes(); this.paramClasses = method.getParameterTypes();
this.paramComposeBeanType = Type pt = createParamComposeBeanType(serviceImplClass, method, actionid, paramTypes, paramClasses);
createParamComposeBeanType(serviceImplClass, method, actionid, paramTypes, paramClasses); this.paramComposeBeanType = pt;
this.paramComposeBeanCreator =
(pt == null || pt == paramTypes[0]) ? null : Creator.create(TypeToken.typeToClass(pt), 1);
this.method = method; this.method = method;
Annotation[][] anns = method.getParameterAnnotations(); Annotation[][] anns = method.getParameterAnnotations();
int topicAddrIndex = -1; int topicAddrIndex = -1;
@@ -186,7 +191,7 @@ public final class SncpRemoteAction {
this.paramAddressSourceIndex = sourceAddrIndex; this.paramAddressSourceIndex = sourceAddrIndex;
this.paramHandlerIndex = handlerFuncIndex; this.paramHandlerIndex = handlerFuncIndex;
this.paramHandlerClass = handlerFuncClass; this.paramHandlerClass = handlerFuncClass;
this.paramHandlerResultType = handlerResultType; this.paramHandlerType = handlerResultType;
this.paramHandlerAttachIndex = handlerAttachIndex; this.paramHandlerAttachIndex = handlerAttachIndex;
this.header = SncpHeader.create( this.header = SncpHeader.create(
sncpClient == null ? null : sncpClient.getClientSncpAddress(), sncpClient == null ? null : sncpClient.getClientSncpAddress(),
@@ -209,7 +214,7 @@ public final class SncpRemoteAction {
} else { } else {
throw new SncpException(serviceImplClass + " had unknown return genericType in " + method); throw new SncpException(serviceImplClass + " had unknown return genericType in " + method);
} }
this.returnFutureResultType = returnType; this.returnFutureType = returnType;
this.returnFutureClass = method.getReturnType().isAssignableFrom(CompletableFuture.class) this.returnFutureClass = method.getReturnType().isAssignableFrom(CompletableFuture.class)
? CompletableFuture.class ? CompletableFuture.class
: (Class) method.getReturnType(); : (Class) method.getReturnType();
@@ -220,7 +225,7 @@ public final class SncpRemoteAction {
throw new SncpException(serviceImplClass + " return must be CompletableFuture or subclass"); throw new SncpException(serviceImplClass + " return must be CompletableFuture or subclass");
} }
} else { } else {
this.returnFutureResultType = null; this.returnFutureType = null;
this.returnFutureClass = null; this.returnFutureClass = null;
this.returnFutureCreator = null; this.returnFutureCreator = null;
} }
@@ -247,7 +252,7 @@ public final class SncpRemoteAction {
// 动态生成组合JavaBean类 // 动态生成组合JavaBean类
final Class serviceClass = resourceType.getClass(); final Class serviceClass = resourceType.getClass();
final String columnDesc = org.redkale.asm.Type.getDescriptor(ConvertColumn.class); final String columnDesc = org.redkale.asm.Type.getDescriptor(ConvertColumn.class);
final String newDynName = "org/redkaledyn/sncp/servlet/action/_DynSncpActionParamBean__" final String newDynName = "org/redkaledyn/sncp/servlet/action/_DynSncpActionParamBean_"
+ resourceType.getSimpleName() + "_" + method.getName() + "_" + actionid; + resourceType.getSimpleName() + "_" + method.getName() + "_" + actionid;
try { try {
Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
@@ -278,7 +283,7 @@ public final class SncpRemoteAction {
av.visitEnd(); av.visitEnd();
fv.visitEnd(); fv.visitEnd();
} }
{ // 空参数构造函数 { // 空参数构造函数
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null)); mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null));
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
@@ -286,7 +291,7 @@ public final class SncpRemoteAction {
mv.visitMaxs(1, 1); mv.visitMaxs(1, 1);
mv.visitEnd(); mv.visitEnd();
} }
{ // 参数构造函数 { // 一个参数构造函数
mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "<init>", "([Ljava/lang/Object;)V", null, null)); mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "<init>", "([Ljava/lang/Object;)V", null, null));
mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
@@ -306,13 +311,16 @@ public final class SncpRemoteAction {
cw.visitEnd(); cw.visitEnd();
byte[] bytes = cw.toByteArray(); byte[] bytes = cw.toByteArray();
Class newClazz = new ClassLoader(serviceClass.getClassLoader()) { Class newClazz = new ClassLoader(Thread.currentThread().getContextClassLoader()) {
public final Class<?> loadClass(String name, byte[] b) { public final Class<?> loadClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length); return defineClass(name, b, 0, b.length);
} }
}.loadClass(newDynName.replace('/', '.'), bytes); }.loadClass(newDynName.replace('/', '.'), bytes);
RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz); RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz);
RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.')); RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.'));
Creator.load(newClazz);
ProtobufFactory.root().loadDecoder(newClazz);
ProtobufFactory.root().loadEncoder(newClazz);
return newClazz; return newClazz;
} }
} }

View File

@@ -133,7 +133,7 @@ public class SncpRemoteInfo<S extends Service> {
handler.completed( handler.completed(
v == null v == null
? null ? null
: convert.convertFrom(action.paramHandlerResultType, v, 1, v.length - 1), : convert.convertFrom(action.paramHandlerType, v, 1, v.length - 1),
attach); attach);
} else { } else {
handler.failed(t, attach); handler.failed(t, attach);
@@ -144,7 +144,7 @@ public class SncpRemoteInfo<S extends Service> {
if (action.returnFutureClass == CompletableFuture.class) { if (action.returnFutureClass == CompletableFuture.class) {
// v,length-1为了读掉(byte)0 // v,length-1为了读掉(byte)0
return (T) future.thenApply( return (T) future.thenApply(
v -> v == null ? null : convert.convertFrom(action.returnFutureResultType, v, 1, v.length - 1)); v -> v == null ? null : convert.convertFrom(action.returnFutureType, v, 1, v.length - 1));
} else { } else {
final CompletableFuture returnFuture = action.returnFutureCreator.create(); final CompletableFuture returnFuture = action.returnFutureCreator.create();
future.whenComplete((v, t) -> { future.whenComplete((v, t) -> {
@@ -153,7 +153,7 @@ public class SncpRemoteInfo<S extends Service> {
returnFuture.complete( returnFuture.complete(
v == null v == null
? null ? null
: convert.convertFrom(action.returnFutureResultType, v, 1, v.length - 1)); : convert.convertFrom(action.returnFutureType, v, 1, v.length - 1));
} else { } else {
returnFuture.completeExceptionally(t); returnFuture.completeExceptionally(t);
} }
@@ -256,8 +256,13 @@ public class SncpRemoteInfo<S extends Service> {
byte[] body = null; byte[] body = null;
if (myParamTypes.length > 0) { // 存在参数 if (myParamTypes.length > 0) { // 存在参数
ProtobufWriter writer = convert.pollWriter(); ProtobufWriter writer = convert.pollWriter();
for (int i = 0; i < params.length; i++) { // service方法的参数 if (action.paramComposeBeanCreator != null) {
convert.convertTo(writer, myParamTypes[i], params[i]); Object paramBean = action.paramComposeBeanCreator.create(params);
convert.convertTo(writer, action.paramComposeBeanType, paramBean);
} else {
for (int i = 0; i < params.length; i++) { // service方法的参数
convert.convertTo(writer, myParamTypes[i], params[i]);
}
} }
body = writer.toByteArray().content(); body = writer.toByteArray().content();
convert.offerWriter(writer); convert.offerWriter(writer);

View File

@@ -4,9 +4,7 @@
*/ */
package org.redkale.util; package org.redkale.util;
import java.io.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.net.*;
import java.util.*; import java.util.*;
import java.util.AbstractMap.SimpleEntry; import java.util.AbstractMap.SimpleEntry;
import java.util.concurrent.*; import java.util.concurrent.*;
@@ -360,6 +358,16 @@ public interface Creator<T> {
break; break;
} }
} }
if (constructor0 == null && paramCount == 1) {
for (Constructor c : cs) {
int cc = c.getParameterCount();
if (cc == 1 && c.getParameterTypes()[0] == Object[].class) {
constructor0 = c;
constructorParameters0 = new SimpleEntry[1];
break;
}
}
}
} }
if (constructor0 == null) { // 4、查找非private带ConstructorParameters的构造函数 if (constructor0 == null) { // 4、查找非private带ConstructorParameters的构造函数
for (Constructor c : clazz.getDeclaredConstructors()) { for (Constructor c : clazz.getDeclaredConstructors()) {
@@ -439,12 +447,14 @@ public interface Creator<T> {
int paramLen = constructorParameters.length; int paramLen = constructorParameters.length;
Asms.visitInsn(mv, paramLen); Asms.visitInsn(mv, paramLen);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Class"); mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
for (int i = 0; i < constructorParameters.length; i++) { for (int i = 0; i < constructorParameters.length; i++) {
final Class pt = constructorParameters[i].getValue();
mv.visitInsn(DUP); mv.visitInsn(DUP);
Asms.visitInsn(mv, i); Asms.visitInsn(mv, i);
Asms.visitFieldInsn(mv, pt); if (constructorParameters[i] == null) {
mv.visitLdcInsn(Type.getType("[Ljava/lang/Object;"));
} else {
Asms.visitFieldInsn(mv, constructorParameters[i].getValue());
}
mv.visitInsn(AASTORE); mv.visitInsn(AASTORE);
} }
mv.visitInsn(ARETURN); mv.visitInsn(ARETURN);
@@ -454,7 +464,7 @@ public interface Creator<T> {
{ // create 方法 { // create 方法
mv = cw.visitMethod( mv = cw.visitMethod(
ACC_PUBLIC + ACC_VARARGS, "create", "([Ljava/lang/Object;)L" + interName + ";", null, null); ACC_PUBLIC + ACC_VARARGS, "create", "([Ljava/lang/Object;)L" + interName + ";", null, null);
if (constructorParameters.length > 0) { if (constructorParameters.length > 0 && constructorParameters[0] != null) {
av0 = mv.visitAnnotation(Type.getDescriptor(ConstructorParameters.class), true); av0 = mv.visitAnnotation(Type.getDescriptor(ConstructorParameters.class), true);
AnnotationVisitor av1 = av0.visitArray("value"); AnnotationVisitor av1 = av0.visitArray("value");
for (SimpleEntry<String, Class> n : constructorParameters) { for (SimpleEntry<String, Class> n : constructorParameters) {
@@ -463,81 +473,84 @@ public interface Creator<T> {
av1.visitEnd(); av1.visitEnd();
av0.visitEnd(); av0.visitEnd();
} }
{ // 有Primitive数据类型且值为null的参数需要赋默认值 // 有Primitive数据类型且值为null的参数需要赋默认值
for (int i = 0; i < constructorParameters.length; i++) { for (int i = 0; i < constructorParameters.length; i++) {
final Class pt = constructorParameters[i].getValue(); if (constructorParameters[i] == null) {
if (!pt.isPrimitive()) { continue;
continue;
}
mv.visitVarInsn(ALOAD, 1);
Asms.visitInsn(mv, i);
mv.visitInsn(AALOAD);
Label lab = new Label();
mv.visitJumpInsn(IFNONNULL, lab);
mv.visitVarInsn(ALOAD, 1);
Asms.visitInsn(mv, i);
if (pt == int.class) {
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(
INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
} else if (pt == long.class) {
mv.visitInsn(LCONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
} else if (pt == boolean.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "FALSE", "Ljava/lang/Boolean;");
} else if (pt == short.class) {
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
} else if (pt == float.class) {
mv.visitInsn(FCONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
} else if (pt == byte.class) {
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
} else if (pt == double.class) {
mv.visitInsn(DCONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
} else if (pt == char.class) {
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(
INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
}
mv.visitInsn(AASTORE);
mv.visitLabel(lab);
} }
final Class pt = constructorParameters[i].getValue();
if (!pt.isPrimitive()) {
continue;
}
mv.visitVarInsn(ALOAD, 1);
Asms.visitInsn(mv, i);
mv.visitInsn(AALOAD);
Label lab = new Label();
mv.visitJumpInsn(IFNONNULL, lab);
mv.visitVarInsn(ALOAD, 1);
Asms.visitInsn(mv, i);
if (pt == int.class) {
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
} else if (pt == long.class) {
mv.visitInsn(LCONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
} else if (pt == boolean.class) {
mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "FALSE", "Ljava/lang/Boolean;");
} else if (pt == short.class) {
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false);
} else if (pt == float.class) {
mv.visitInsn(FCONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false);
} else if (pt == byte.class) {
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false);
} else if (pt == double.class) {
mv.visitInsn(DCONST_0);
mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false);
} else if (pt == char.class) {
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(
INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", false);
}
mv.visitInsn(AASTORE);
mv.visitLabel(lab);
} }
mv.visitTypeInsn(NEW, interName); mv.visitTypeInsn(NEW, interName);
mv.visitInsn(DUP); mv.visitInsn(DUP);
// --------------------------------------- // ---------------------------------------
{ for (int i = 0; i < constructorParameters.length; i++) {
for (int i = 0; i < constructorParameters.length; i++) { if (constructorParameters[i] == null) {
mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 1);
Asms.visitInsn(mv, i); break;
mv.visitInsn(AALOAD); }
final Class ct = constructorParameters[i].getValue(); mv.visitVarInsn(ALOAD, 1);
if (ct.isPrimitive()) { Asms.visitInsn(mv, i);
final Class bigct = TypeToken.primitiveToWrapper(ct); mv.visitInsn(AALOAD);
mv.visitTypeInsn(CHECKCAST, bigct.getName().replace('.', '/')); final Class ct = constructorParameters[i].getValue();
try { if (ct.isPrimitive()) {
Method pm = bigct.getMethod(ct.getSimpleName() + "Value"); final Class bigct = TypeToken.primitiveToWrapper(ct);
mv.visitMethodInsn( mv.visitTypeInsn(CHECKCAST, bigct.getName().replace('.', '/'));
INVOKEVIRTUAL, try {
bigct.getName().replace('.', '/'), Method pm = bigct.getMethod(ct.getSimpleName() + "Value");
pm.getName(), mv.visitMethodInsn(
Type.getMethodDescriptor(pm), INVOKEVIRTUAL,
false); bigct.getName().replace('.', '/'),
} catch (Exception ex) { pm.getName(),
throw new RedkaleException(ex); // 不可能会发生 Type.getMethodDescriptor(pm),
} false);
} else { } catch (Exception ex) {
mv.visitTypeInsn(CHECKCAST, ct.getName().replace('.', '/')); throw new RedkaleException(ex); // 不可能会发生
} }
} else {
mv.visitTypeInsn(CHECKCAST, ct.getName().replace('.', '/'));
} }
} }
// --------------------------------------- // ---------------------------------------
mv.visitMethodInsn(INVOKESPECIAL, interName, "<init>", Type.getConstructorDescriptor(constructor), false); mv.visitMethodInsn(INVOKESPECIAL, interName, "<init>", Type.getConstructorDescriptor(constructor), false);
mv.visitInsn(ARETURN); mv.visitInsn(ARETURN);
mv.visitMaxs((constructorParameters.length > 0 ? (constructorParameters.length + 3) : 2), 2); mv.visitMaxs(3, 2);
mv.visitEnd(); mv.visitEnd();
} }
{ // 虚拟 create 方法 { // 虚拟 create 方法
@@ -555,52 +568,17 @@ public interface Creator<T> {
mv.visitEnd(); mv.visitEnd();
} }
cw.visitEnd(); cw.visitEnd();
final byte[] bytes = cw.toByteArray();
final boolean ispub = Modifier.isPublic(constructor.getModifiers());
Class<?> resultClazz = null;
if (loader instanceof URLClassLoader && !ispub) {
try {
final URLClassLoader urlLoader = (URLClassLoader) loader;
final URL url = new URL(
"memclass", "localhost", -1, "/" + newDynName.replace('/', '.') + "/", new URLStreamHandler() {
@Override
protected URLConnection openConnection(URL u) throws IOException {
return new URLConnection(u) {
@Override
public void connect() throws IOException {
// do nothing
}
@Override byte[] bytes = cw.toByteArray();
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(bytes);
}
};
}
});
Method addURLMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
addURLMethod.setAccessible(true);
addURLMethod.invoke(urlLoader, url);
resultClazz = urlLoader.loadClass(newDynName.replace('/', '.'));
} catch (Throwable t) { // 异常无需理会, 使用下一种loader方式
t.printStackTrace();
}
}
if (!ispub && resultClazz == null) {
throw new RedkaleException(
"[" + clazz + "] have no public or ConstructorParameters-Annotation constructor.");
}
try { try {
if (resultClazz == null) { Class newClazz = new ClassLoader(loader) {
resultClazz = new ClassLoader(loader) { public final Class<?> loadClass(String name, byte[] b) {
public final Class<?> loadClass(String name, byte[] b) { return defineClass(name, b, 0, b.length);
return defineClass(name, b, 0, b.length); }
} }.loadClass(newDynName.replace('/', '.'), bytes);
}.loadClass(newDynName.replace('/', '.'), bytes); RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz);
} RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.'));
RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, resultClazz); return (Creator) newClazz.getDeclaredConstructor().newInstance();
RedkaleClassLoader.putReflectionDeclaredConstructors(resultClazz, newDynName.replace('/', '.'));
return (Creator) resultClazz.getDeclaredConstructor().newInstance();
} catch (Exception ex) { } catch (Exception ex) {
throw new RedkaleException(ex); throw new RedkaleException(ex);
} }

View File

@@ -29,6 +29,7 @@ public class SncpSleepTest {
@Test @Test
public void run() throws Exception { public void run() throws Exception {
Creator.create(List.class);
System.out.println("------------------- 并发调用 -----------------------------------"); System.out.println("------------------- 并发调用 -----------------------------------");
final Application application = Application.create(true); final Application application = Application.create(true);
final ExecutorService workExecutor = WorkThread.createWorkExecutor(10, "Thread-Work-%s"); final ExecutorService workExecutor = WorkThread.createWorkExecutor(10, "Thread-Work-%s");

View File

@@ -36,17 +36,17 @@ public class DynActionTestService_change extends SncpActionServlet {
public void action(SncpRequest request, SncpResponse response) throws Throwable { public void action(SncpRequest request, SncpResponse response) throws Throwable {
Convert<Reader, Writer> convert = request.getConvert(); Convert<Reader, Writer> convert = request.getConvert();
Reader in = request.getReader(); Reader in = request.getReader();
DynActionTestService_change_paramBean bean = convert.convertFrom(paramComposeBeanType, in); DynSncpActionParamBean_TestService_change bean = convert.convertFrom(paramComposeBeanType, in);
TestService serviceObj = (TestService) service(); TestService serviceObj = (TestService) service();
Object rs = serviceObj.change(bean.arg1, bean.arg2, bean.arg3); Object rs = serviceObj.change(bean.arg1, bean.arg2, bean.arg3);
response.finish(boolean.class, rs); response.finish(boolean.class, rs);
} }
public static class DynActionTestService_change_paramBean { public static class DynSncpActionParamBean_TestService_change {
public DynActionTestService_change_paramBean() {} public DynSncpActionParamBean_TestService_change() {}
public DynActionTestService_change_paramBean(Object[] params) { public DynSncpActionParamBean_TestService_change(Object[] params) {
this.arg1 = (TestBean) params[0]; this.arg1 = (TestBean) params[0];
this.arg2 = (String) params[1]; this.arg2 = (String) params[1];
this.arg3 = (int) params[2]; this.arg3 = (int) params[2];

View File

@@ -37,17 +37,17 @@ public class DynActionTestService_changeName extends SncpActionServlet {
public void action(SncpRequest request, SncpResponse response) throws Throwable { public void action(SncpRequest request, SncpResponse response) throws Throwable {
Convert<Reader, Writer> convert = request.getConvert(); Convert<Reader, Writer> convert = request.getConvert();
Reader in = request.getReader(); Reader in = request.getReader();
DynActionTestService_changeName_paramBean bean = convert.convertFrom(paramComposeBeanType, in); DynSncpActionParamBean_TestService_changeName bean = convert.convertFrom(paramComposeBeanType, in);
TestService serviceObj = (TestService) service(); TestService serviceObj = (TestService) service();
CompletableFuture future = serviceObj.changeName(bean.arg1, bean.arg2, bean.arg3); CompletableFuture future = serviceObj.changeName(bean.arg1, bean.arg2, bean.arg3);
response.finishFuture(paramHandlerResultType, future); response.finishFuture(paramHandlerType, future);
} }
public static class DynActionTestService_changeName_paramBean { public static class DynSncpActionParamBean_TestService_changeName {
public DynActionTestService_changeName_paramBean() {} public DynSncpActionParamBean_TestService_changeName() {}
public DynActionTestService_changeName_paramBean(Object[] params) { public DynSncpActionParamBean_TestService_changeName(Object[] params) {
this.arg1 = (TestBean) params[0]; this.arg1 = (TestBean) params[0];
this.arg2 = (String) params[1]; this.arg2 = (String) params[1];
this.arg3 = (int) params[2]; this.arg3 = (int) params[2];

View File

@@ -36,18 +36,18 @@ public class DynActionTestService_insert extends SncpActionServlet {
public void action(SncpRequest request, SncpResponse response) throws Throwable { public void action(SncpRequest request, SncpResponse response) throws Throwable {
Convert<Reader, Writer> convert = request.getConvert(); Convert<Reader, Writer> convert = request.getConvert();
Reader in = request.getReader(); Reader in = request.getReader();
DynActionTestService_insert_paramBean bean = convert.convertFrom(paramComposeBeanType, in); DynSncpActionParamBean_TestService_insert bean = convert.convertFrom(paramComposeBeanType, in);
bean.arg0 = response.getParamAsyncHandler(); bean.arg0 = response.getParamAsyncHandler();
TestService serviceObj = (TestService) service(); TestService serviceObj = (TestService) service();
serviceObj.insert(bean.arg0, bean.arg1, bean.arg2, bean.arg3); serviceObj.insert(bean.arg0, bean.arg1, bean.arg2, bean.arg3);
response.finishVoid(); response.finishVoid();
} }
public static class DynActionTestService_insert_paramBean { public static class DynSncpActionParamBean_TestService_insert {
public DynActionTestService_insert_paramBean() {} public DynSncpActionParamBean_TestService_insert() {}
public DynActionTestService_insert_paramBean(Object[] params) { public DynSncpActionParamBean_TestService_insert(Object[] params) {
this.arg0 = (BooleanHandler) params[0]; this.arg0 = (BooleanHandler) params[0];
this.arg1 = (TestBean) params[1]; this.arg1 = (TestBean) params[1];
this.arg2 = (String) params[2]; this.arg2 = (String) params[2];

View File

@@ -37,18 +37,18 @@ public class DynActionTestService_update extends SncpActionServlet {
public void action(SncpRequest request, SncpResponse response) throws Throwable { public void action(SncpRequest request, SncpResponse response) throws Throwable {
Convert<Reader, Writer> convert = request.getConvert(); Convert<Reader, Writer> convert = request.getConvert();
Reader in = request.getReader(); Reader in = request.getReader();
DynActionTestService_update_paramBean bean = convert.convertFrom(paramComposeBeanType, in); DynSncpActionParamBean_TestService_update bean = convert.convertFrom(paramComposeBeanType, in);
bean.arg3 = response.getParamAsyncHandler(); bean.arg3 = response.getParamAsyncHandler();
TestService serviceObj = (TestService) service(); TestService serviceObj = (TestService) service();
serviceObj.update(bean.arg1, bean.arg2, bean.arg3, bean.arg4, bean.arg5, bean.arg6); serviceObj.update(bean.arg1, bean.arg2, bean.arg3, bean.arg4, bean.arg5, bean.arg6);
response.finishVoid(); response.finishVoid();
} }
public static class DynActionTestService_update_paramBean { public static class DynSncpActionParamBean_TestService_update {
public DynActionTestService_update_paramBean() {} public DynSncpActionParamBean_TestService_update() {}
public DynActionTestService_update_paramBean(Object[] params) { public DynSncpActionParamBean_TestService_update(Object[] params) {
this.arg1 = (long) params[0]; this.arg1 = (long) params[0];
this.arg2 = (short) params[1]; this.arg2 = (short) params[1];
this.arg3 = (CompletionHandler) params[2]; this.arg3 = (CompletionHandler) params[2];

View File

@@ -31,6 +31,10 @@ public class CreatorRecord {
public CreatorRecord() {} public CreatorRecord() {}
public CreatorRecord(Object[] arg) {
System.out.println("creat CreatorRecord!");
}
@ConstructorParameters({"id", "name", "lval", "tval", "bval", "sval", "cval", "fval", "dval"}) @ConstructorParameters({"id", "name", "lval", "tval", "bval", "sval", "cval", "fval", "dval"})
public CreatorRecord( public CreatorRecord(
int id, String name, long lval, boolean tval, byte bval, short sval, char cval, float fval, double dval) { int id, String name, long lval, boolean tval, byte bval, short sval, char cval, float fval, double dval) {

View File

@@ -19,6 +19,7 @@ public class CreatorTest {
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
CreatorTest test = new CreatorTest(); CreatorTest test = new CreatorTest();
test.run1(); test.run1();
test.run2();
} }
@Test @Test
@@ -35,4 +36,10 @@ public class CreatorTest {
Assertions.assertEquals("ss", record.getName()); Assertions.assertEquals("ss", record.getName());
Assertions.assertEquals(json, json2); Assertions.assertEquals(json, json2);
} }
@Test
public void run2() throws Throwable {
Creator<CreatorRecord> creator = Creator.create(CreatorRecord.class, 1);
creator.create(null, null);
}
} }