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