Request增加Annotation[]属性

This commit is contained in:
redkale
2024-09-04 17:09:39 +08:00
parent 4c6403a4ca
commit 01c8aca36a
5 changed files with 108 additions and 11 deletions

View File

@@ -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());
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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()][];

View File

@@ -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();