Request增加Annotation[]属性
This commit is contained in:
@@ -85,9 +85,9 @@ public class MessageModuleEngine extends ModuleEngine {
|
||||
|
||||
// 在doInstance方法里被调用
|
||||
void addMessageConsumer(MessageConsumer consumer) {
|
||||
String mqName = environment.getPropertyValue(
|
||||
consumer.getClass().getAnnotation(ResourceConsumer.class).mq());
|
||||
if (findMessageAgent(mqName) == null) {
|
||||
ResourceConsumer rc = consumer.getClass().getAnnotation(ResourceConsumer.class);
|
||||
String mqName = environment.getPropertyValue(rc.mq());
|
||||
if (rc.required() && findMessageAgent(mqName) == null) {
|
||||
throw new RedkaleException("Not found " + MessageAgent.class.getSimpleName() + "(name = " + mqName + ") on "
|
||||
+ consumer.getClass().getName());
|
||||
}
|
||||
|
||||
@@ -6,11 +6,14 @@
|
||||
package org.redkale.net;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Array;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
import org.redkale.convert.ConvertDisabled;
|
||||
import org.redkale.convert.bson.BsonConvert;
|
||||
import org.redkale.convert.json.JsonConvert;
|
||||
import org.redkale.util.Creator;
|
||||
|
||||
/**
|
||||
* 协议请求对象
|
||||
@@ -44,6 +47,9 @@ public abstract class Request<C extends Context> {
|
||||
|
||||
protected String traceid;
|
||||
|
||||
// Service动态生成接口的方法上的注解
|
||||
protected Annotation[] annotations;
|
||||
|
||||
protected AsyncConnection channel;
|
||||
|
||||
/** properties 与 attributes 的区别在于:调用recycle时, attributes会被清空而properties会保留; properties 通常存放需要永久绑定在request里的一些对象 */
|
||||
@@ -68,6 +74,7 @@ public abstract class Request<C extends Context> {
|
||||
this.pipelineCount = request.pipelineCount;
|
||||
this.pipelineCompleted = request.pipelineCompleted;
|
||||
this.traceid = request.traceid;
|
||||
this.annotations = request.annotations;
|
||||
this.channel = request.channel;
|
||||
}
|
||||
|
||||
@@ -103,6 +110,7 @@ public abstract class Request<C extends Context> {
|
||||
completed = false;
|
||||
keepAlive = false;
|
||||
attributes.clear();
|
||||
annotations = null;
|
||||
channel = null; // close it by response
|
||||
}
|
||||
|
||||
@@ -160,6 +168,38 @@ public abstract class Request<C extends Context> {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public Annotation[] getAnnotations() {
|
||||
if (annotations == null) {
|
||||
return new Annotation[0];
|
||||
}
|
||||
return Arrays.copyOfRange(annotations, 0, annotations.length);
|
||||
}
|
||||
|
||||
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
|
||||
if (annotations != null) {
|
||||
for (Annotation ann : annotations) {
|
||||
if (ann.annotationType() == annotationClass) {
|
||||
return annotationClass.cast(ann);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass) {
|
||||
if (annotations == null) {
|
||||
return (T[]) Array.newInstance(annotationClass, 0);
|
||||
} else {
|
||||
List<T> list = new ArrayList<>();
|
||||
for (Annotation ann : annotations) {
|
||||
if (ann.annotationType() == annotationClass) {
|
||||
list.add(annotationClass.cast(ann));
|
||||
}
|
||||
}
|
||||
return list.toArray(Creator.funcArray(annotationClass));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getCreateTime()
|
||||
* @return long
|
||||
|
||||
@@ -315,6 +315,10 @@ public class HttpRequest extends Request<HttpContext> {
|
||||
this.keepAlive = keepAlive;
|
||||
}
|
||||
|
||||
protected void setAnnotations(Annotation[] annotations) {
|
||||
this.annotations = annotations;
|
||||
}
|
||||
|
||||
protected ConvertType getRespConvertType() {
|
||||
return this.respConvertType;
|
||||
}
|
||||
|
||||
@@ -65,13 +65,17 @@ public final class Rest {
|
||||
|
||||
static final String REST_SERVICE_FIELD_NAME = "_redkale_service";
|
||||
|
||||
static final String REST_SERVICEMAP_FIELD_NAME =
|
||||
"_redkale_serviceMap"; // 如果只有name=""的Service资源,则实例中_servicemap必须为null
|
||||
// 如果只有name=""的Service资源,则实例中_servicemap必须为null
|
||||
static final String REST_SERVICEMAP_FIELD_NAME = "_redkale_serviceMap";
|
||||
|
||||
private static final String REST_PARAMTYPES_FIELD_NAME =
|
||||
"_redkale_paramTypes"; // 存在泛型的参数数组 Type[][] 第1维度是方法的下标, 第二维度是参数的下标
|
||||
// 存在存在方法注解数组 Annotation[][] 第1维度是方法的下标, 第二维度是参数的下标
|
||||
private static final String REST_METHOD_ANNS_NAME = "_redkale_methodAnns";
|
||||
|
||||
private static final String REST_RETURNTYPES_FIELD_NAME = "_redkale_returnTypes"; // 存在泛型的结果数组
|
||||
// 存在泛型的参数数组 Type[][] 第1维度是方法的下标, 第二维度是参数的下标
|
||||
private static final String REST_PARAMTYPES_FIELD_NAME = "_redkale_paramTypes";
|
||||
|
||||
// 存在泛型的结果数组
|
||||
private static final String REST_RETURNTYPES_FIELD_NAME = "_redkale_returnTypes";
|
||||
|
||||
private static final java.lang.reflect.Type TYPE_RETRESULT_STRING = new TypeToken<RetResult<String>>() {}.getType();
|
||||
|
||||
@@ -291,6 +295,12 @@ public final class Rest {
|
||||
return "http.resp.";
|
||||
}
|
||||
|
||||
// 仅供Rest动态构建里使用
|
||||
@ClassDepends
|
||||
public static void setRequestAnnotations(HttpRequest request, Annotation[] annotations) {
|
||||
request.setAnnotations(annotations);
|
||||
}
|
||||
|
||||
// 仅供Rest动态构建里 currentUserid() 使用
|
||||
@ClassDepends
|
||||
public static <T> T orElse(T t, T defValue) {
|
||||
@@ -1306,6 +1316,7 @@ public final class Rest {
|
||||
final Map<String, Object> classMap = new LinkedHashMap<>();
|
||||
|
||||
final List<MappingEntry> entrys = new ArrayList<>();
|
||||
final List<Annotation[]> methodAnns = new ArrayList<>();
|
||||
final List<java.lang.reflect.Type[]> paramTypes = new ArrayList<>();
|
||||
final List<java.lang.reflect.Type> retvalTypes = new ArrayList<>();
|
||||
|
||||
@@ -1352,7 +1363,7 @@ public final class Rest {
|
||||
if (mappings == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
methodAnns.add(method.getAnnotations());
|
||||
java.lang.reflect.Type[] ptypes =
|
||||
TypeToken.getGenericType(method.getGenericParameterTypes(), serviceType);
|
||||
for (java.lang.reflect.Type t : ptypes) {
|
||||
@@ -1368,6 +1379,7 @@ public final class Rest {
|
||||
+ ", serviceType is " + serviceType.getName());
|
||||
}
|
||||
retvalTypes.add(rtype);
|
||||
|
||||
if (mappings.isEmpty()) { // 没有Mapping,设置一个默认值
|
||||
MappingEntry entry = new MappingEntry(
|
||||
serRpcOnly,
|
||||
@@ -1754,6 +1766,12 @@ public final class Rest {
|
||||
JsonFactory childFactory = createJsonFactory((RestConvert[]) rc[0], (RestConvertCoder[]) rc[1]);
|
||||
genField.set(obj, childFactory.getConvert());
|
||||
}
|
||||
Field annsfield = newClazz.getDeclaredField(REST_METHOD_ANNS_NAME);
|
||||
annsfield.setAccessible(true);
|
||||
Annotation[][] methodAnnArray = new Annotation[methodAnns.size()][];
|
||||
methodAnnArray = methodAnns.toArray(methodAnnArray);
|
||||
annsfield.set(obj, methodAnnArray);
|
||||
|
||||
Field typesfield = newClazz.getDeclaredField(REST_PARAMTYPES_FIELD_NAME);
|
||||
typesfield.setAccessible(true);
|
||||
java.lang.reflect.Type[][] paramtypeArray = new java.lang.reflect.Type[paramTypes.size()][];
|
||||
@@ -1866,6 +1884,7 @@ public final class Rest {
|
||||
final Map<String, org.redkale.util.Attribute> restAttributes = new LinkedHashMap<>();
|
||||
final Map<String, Object> classMap = new LinkedHashMap<>();
|
||||
final Map<java.lang.reflect.Type, String> typeRefs = new LinkedHashMap<>();
|
||||
final List<Annotation[]> methodAnns = new ArrayList<>();
|
||||
final List<java.lang.reflect.Type[]> paramTypes = new ArrayList<>();
|
||||
final List<java.lang.reflect.Type> retvalTypes = new ArrayList<>();
|
||||
final Map<String, java.lang.reflect.Type> bodyTypes = new HashMap<>();
|
||||
@@ -1926,6 +1945,7 @@ public final class Rest {
|
||||
}
|
||||
}
|
||||
}
|
||||
methodAnns.add(method.getAnnotations());
|
||||
java.lang.reflect.Type[] ptypes = TypeToken.getGenericType(method.getGenericParameterTypes(), serviceType);
|
||||
for (java.lang.reflect.Type t : ptypes) {
|
||||
if (!TypeToken.isClassType(t)) {
|
||||
@@ -2160,6 +2180,19 @@ public final class Rest {
|
||||
mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] {serviceTypeInternalName});
|
||||
mv.visitVarInsn(ASTORE, 3);
|
||||
|
||||
// 执行setRequestAnnotations
|
||||
mv.visitVarInsn(ALOAD, 1);
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitFieldInsn(GETFIELD, newDynName, REST_METHOD_ANNS_NAME, "[[Ljava/lang/annotation/Annotation;");
|
||||
Asms.visitInsn(mv, entry.methodIdx); // 方法下标
|
||||
mv.visitInsn(AALOAD);
|
||||
mv.visitMethodInsn(
|
||||
INVOKESTATIC,
|
||||
restInternalName,
|
||||
"setRequestAnnotations",
|
||||
"(" + reqDesc + "[Ljava/lang/annotation/Annotation;)V",
|
||||
false);
|
||||
|
||||
final int maxStack = 3 + params.length;
|
||||
List<int[]> varInsns = new ArrayList<>();
|
||||
int maxLocals = 4;
|
||||
@@ -4153,6 +4186,17 @@ public final class Rest {
|
||||
fv.visitEnd();
|
||||
}
|
||||
|
||||
{ // _methodAnns字段 Annotation[][]
|
||||
fv = cw.visitField(ACC_PRIVATE, REST_METHOD_ANNS_NAME, "[[Ljava/lang/annotation/Annotation;", null, null);
|
||||
av0 = fv.visitAnnotation(Type.getDescriptor(Comment.class), true);
|
||||
StringBuilder sb = new StringBuilder().append('[');
|
||||
for (Annotation[] rs : methodAnns) {
|
||||
sb.append(Arrays.toString(rs)).append(',');
|
||||
}
|
||||
av0.visit("value", sb.append(']').toString());
|
||||
av0.visitEnd();
|
||||
fv.visitEnd();
|
||||
}
|
||||
{ // _paramtypes字段 java.lang.reflect.Type[][]
|
||||
fv = cw.visitField(ACC_PRIVATE, REST_PARAMTYPES_FIELD_NAME, "[[Ljava/lang/reflect/Type;", null, null);
|
||||
av0 = fv.visitAnnotation(Type.getDescriptor(Comment.class), true);
|
||||
@@ -4243,6 +4287,13 @@ public final class Rest {
|
||||
genField.set(obj, childFactory.getConvert());
|
||||
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), genField);
|
||||
}
|
||||
Field annsfield = newClazz.getDeclaredField(REST_METHOD_ANNS_NAME);
|
||||
annsfield.setAccessible(true);
|
||||
Annotation[][] methodAnnArray = new Annotation[methodAnns.size()][];
|
||||
methodAnnArray = methodAnns.toArray(methodAnnArray);
|
||||
annsfield.set(obj, methodAnnArray);
|
||||
RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), annsfield);
|
||||
|
||||
Field typesfield = newClazz.getDeclaredField(REST_PARAMTYPES_FIELD_NAME);
|
||||
typesfield.setAccessible(true);
|
||||
java.lang.reflect.Type[][] paramtypeArray = new java.lang.reflect.Type[paramTypes.size()][];
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
*/
|
||||
package org.redkale.util;
|
||||
|
||||
import static org.redkale.asm.Opcodes.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.*;
|
||||
import java.math.*;
|
||||
@@ -16,6 +14,7 @@ import java.util.function.*;
|
||||
import java.util.logging.*;
|
||||
import java.util.stream.Stream;
|
||||
import org.redkale.asm.*;
|
||||
import static org.redkale.asm.Opcodes.*;
|
||||
|
||||
/** @author zhangjx */
|
||||
class Inners {
|
||||
@@ -224,6 +223,9 @@ class Inners {
|
||||
}
|
||||
|
||||
public static <T> IntFunction<T[]> createArrayFunction(final Class<T> clazz) {
|
||||
if (Utility.inNativeImage()) {
|
||||
return t -> (T[]) Array.newInstance(clazz, t);
|
||||
}
|
||||
final String interName = clazz.getName().replace('.', '/');
|
||||
final String interDesc = org.redkale.asm.Type.getDescriptor(clazz);
|
||||
final ClassLoader loader = clazz.getClassLoader();
|
||||
|
||||
Reference in New Issue
Block a user