Avoid cloning empty Annotation array in TypeDescriptor (backport)
Closes gh-32405
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2023 the original author or authors.
|
||||
* Copyright 2002-2024 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -52,8 +52,6 @@ import org.springframework.util.ObjectUtils;
|
||||
@SuppressWarnings("serial")
|
||||
public class TypeDescriptor implements Serializable {
|
||||
|
||||
private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0];
|
||||
|
||||
private static final Map<Class<?>, TypeDescriptor> commonTypesCache = new HashMap<>(32);
|
||||
|
||||
private static final Class<?>[] CACHED_COMMON_TYPES = {
|
||||
@@ -84,7 +82,7 @@ public class TypeDescriptor implements Serializable {
|
||||
public TypeDescriptor(MethodParameter methodParameter) {
|
||||
this.resolvableType = ResolvableType.forMethodParameter(methodParameter);
|
||||
this.type = this.resolvableType.resolve(methodParameter.getNestedParameterType());
|
||||
this.annotatedElement = new AnnotatedElementAdapter(methodParameter.getParameterIndex() == -1 ?
|
||||
this.annotatedElement = AnnotatedElementAdapter.from(methodParameter.getParameterIndex() == -1 ?
|
||||
methodParameter.getMethodAnnotations() : methodParameter.getParameterAnnotations());
|
||||
}
|
||||
|
||||
@@ -96,7 +94,7 @@ public class TypeDescriptor implements Serializable {
|
||||
public TypeDescriptor(Field field) {
|
||||
this.resolvableType = ResolvableType.forField(field);
|
||||
this.type = this.resolvableType.resolve(field.getType());
|
||||
this.annotatedElement = new AnnotatedElementAdapter(field.getAnnotations());
|
||||
this.annotatedElement = AnnotatedElementAdapter.from(field.getAnnotations());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +107,7 @@ public class TypeDescriptor implements Serializable {
|
||||
Assert.notNull(property, "Property must not be null");
|
||||
this.resolvableType = ResolvableType.forMethodParameter(property.getMethodParameter());
|
||||
this.type = this.resolvableType.resolve(property.getType());
|
||||
this.annotatedElement = new AnnotatedElementAdapter(property.getAnnotations());
|
||||
this.annotatedElement = AnnotatedElementAdapter.from(property.getAnnotations());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,7 +123,7 @@ public class TypeDescriptor implements Serializable {
|
||||
public TypeDescriptor(ResolvableType resolvableType, @Nullable Class<?> type, @Nullable Annotation[] annotations) {
|
||||
this.resolvableType = resolvableType;
|
||||
this.type = (type != null ? type : resolvableType.toClass());
|
||||
this.annotatedElement = new AnnotatedElementAdapter(annotations);
|
||||
this.annotatedElement = AnnotatedElementAdapter.from(annotations);
|
||||
}
|
||||
|
||||
|
||||
@@ -512,12 +510,16 @@ public class TypeDescriptor implements Serializable {
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (Annotation ann : getAnnotations()) {
|
||||
builder.append('@').append(ann.annotationType().getName()).append(' ');
|
||||
builder.append('@').append(getName(ann.annotationType())).append(' ');
|
||||
}
|
||||
builder.append(getResolvableType());
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static String getName(Class<?> clazz) {
|
||||
String canonicalName = clazz.getCanonicalName();
|
||||
return (canonicalName != null ? canonicalName : clazz.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new type descriptor for an object.
|
||||
@@ -733,15 +735,23 @@ public class TypeDescriptor implements Serializable {
|
||||
* @see AnnotatedElementUtils#isAnnotated(AnnotatedElement, Class)
|
||||
* @see AnnotatedElementUtils#getMergedAnnotation(AnnotatedElement, Class)
|
||||
*/
|
||||
private class AnnotatedElementAdapter implements AnnotatedElement, Serializable {
|
||||
private static final class AnnotatedElementAdapter implements AnnotatedElement, Serializable {
|
||||
|
||||
private static final AnnotatedElementAdapter EMPTY = new AnnotatedElementAdapter(new Annotation[0]);
|
||||
|
||||
@Nullable
|
||||
private final Annotation[] annotations;
|
||||
|
||||
public AnnotatedElementAdapter(@Nullable Annotation[] annotations) {
|
||||
private AnnotatedElementAdapter(Annotation[] annotations) {
|
||||
this.annotations = annotations;
|
||||
}
|
||||
|
||||
private static AnnotatedElementAdapter from(@Nullable Annotation[] annotations) {
|
||||
if (annotations == null || annotations.length == 0) {
|
||||
return EMPTY;
|
||||
}
|
||||
return new AnnotatedElementAdapter(annotations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass) {
|
||||
for (Annotation annotation : getAnnotations()) {
|
||||
@@ -766,7 +776,7 @@ public class TypeDescriptor implements Serializable {
|
||||
|
||||
@Override
|
||||
public Annotation[] getAnnotations() {
|
||||
return (this.annotations != null ? this.annotations.clone() : EMPTY_ANNOTATION_ARRAY);
|
||||
return (isEmpty() ? this.annotations : this.annotations.clone());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -775,7 +785,7 @@ public class TypeDescriptor implements Serializable {
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return ObjectUtils.isEmpty(this.annotations);
|
||||
return (this.annotations.length == 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -791,7 +801,7 @@ public class TypeDescriptor implements Serializable {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return TypeDescriptor.this.toString();
|
||||
return "AnnotatedElementAdapter annotations=" + Arrays.toString(this.annotations);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user