AnnotationBeanNameGenerator caches meta-annotations for stereotype check

Closes gh-24980
This commit is contained in:
Juergen Hoeller 2020-04-27 13:47:58 +02:00
parent 73fadd8b7c
commit 57f1e86a35
1 changed files with 19 additions and 9 deletions

View File

@ -17,8 +17,10 @@
package org.springframework.context.annotation; package org.springframework.context.annotation;
import java.beans.Introspector; import java.beans.Introspector;
import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
@ -70,6 +72,8 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator {
private static final String COMPONENT_ANNOTATION_CLASSNAME = "org.springframework.stereotype.Component"; private static final String COMPONENT_ANNOTATION_CLASSNAME = "org.springframework.stereotype.Component";
private final Map<String, Set<String>> metaAnnotationTypesCache = new ConcurrentHashMap<>();
@Override @Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
@ -96,16 +100,22 @@ public class AnnotationBeanNameGenerator implements BeanNameGenerator {
String beanName = null; String beanName = null;
for (String type : types) { for (String type : types) {
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type); AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);
if (attributes != null && isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) { if (attributes != null) {
Object value = attributes.get("value"); Set<String> metaTypes = this.metaAnnotationTypesCache.computeIfAbsent(type, key -> {
if (value instanceof String) { Set<String> result = amd.getMetaAnnotationTypes(key);
String strVal = (String) value; return (result.isEmpty() ? Collections.emptySet() : result);
if (StringUtils.hasLength(strVal)) { });
if (beanName != null && !strVal.equals(beanName)) { if (isStereotypeWithNameValue(type, metaTypes, attributes)) {
throw new IllegalStateException("Stereotype annotations suggest inconsistent " + Object value = attributes.get("value");
"component names: '" + beanName + "' versus '" + strVal + "'"); if (value instanceof String) {
String strVal = (String) value;
if (StringUtils.hasLength(strVal)) {
if (beanName != null && !strVal.equals(beanName)) {
throw new IllegalStateException("Stereotype annotations suggest inconsistent " +
"component names: '" + beanName + "' versus '" + strVal + "'");
}
beanName = strVal;
} }
beanName = strVal;
} }
} }
} }