javascript
Spring注解编程基石(四)
目錄
AnnotationsScanner
掃描方法
掃描source為Class方法
掃描source為Method方法
輔助方法
?
MergedAnnotationSelector
MergedAnnotationSelectors.Nearest
MergedAnnotationSelectors.FirstDirectlyDeclared
AnnotationTypeMapping
AnnotationTypeMapping.MirrorSets
MirrorSet
MirrorSets
屬性
構造過程
生成別名信息(直接AliasFor)
全層級處理別名信息
生成方便訪問屬性的信息
AnnotationTypeMappings
AnnotationTypeMapping幫助理解示例
注解定義
注解使用
Spring注解編程基石(一)
Spring注解編程基石(二)
Spring注解編程基石(三)
Spring注解編程基石(四)???????
AnnotationsScanner
在AnnotatedElement的注解層級中查找相關Annotation的掃描器
掃描方法
@Nullable//掃描獲取注解static <C, R> R scan(C context, AnnotatedElement source, SearchStrategy searchStrategy,AnnotationsProcessor<C, R> processor) {return scan(context, source, searchStrategy, processor, null);}@Nullablestatic <C, R> R scan(C context, AnnotatedElement source, SearchStrategy searchStrategy,AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter) {R result = process(context, source, searchStrategy, processor, classFilter);return processor.finish(result);}@Nullableprivate static <C, R> R process(C context, AnnotatedElement source,SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor,@Nullable BiPredicate<C, Class<?>> classFilter) {//source為類if (source instanceof Class) {return processClass(context, (Class<?>) source, searchStrategy, processor, classFilter);}//source為方法if (source instanceof Method) {return processMethod(context, (Method) source, searchStrategy, processor, classFilter);}return processElement(context, source, processor, classFilter);}掃描source為Class方法
@Nullable//根據查找策略掃描Classprivate static <C, R> R processClass(C context, Class<?> source,SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor,@Nullable BiPredicate<C, Class<?>> classFilter) {switch (searchStrategy) {case DIRECT:return processElement(context, source, processor, classFilter);case INHERITED_ANNOTATIONS:return processClassInheritedAnnotations(context, source, searchStrategy, processor, classFilter);case SUPERCLASS:return processClassHierarchy(context, source, processor, classFilter, false, false);case TYPE_HIERARCHY:return processClassHierarchy(context, source, processor, classFilter, true, false);case TYPE_HIERARCHY_AND_ENCLOSING_CLASSES:return processClassHierarchy(context, source, processor, classFilter, true, true);}throw new IllegalStateException("Unsupported search strategy " + searchStrategy);}@Nullable//查找直接注解策略private static <C, R> R processElement(C context, AnnotatedElement source,AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter) {R result = processor.doWithAggregate(context, 0);return (result != null ? result : processor.doWithAnnotations(context, 0, source, getDeclaredAnnotations(context, source, classFilter, false)));}@Nullable//查找繼承注解策略private static <C, R> R processClassInheritedAnnotations(C context, Class<?> source,SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter) {//如果沒有層級,則返回查找直接注解結果if (isWithoutHierarchy(source, searchStrategy)) {return processElement(context, source, processor, classFilter);}Annotation[] relevant = null;int remaining = Integer.MAX_VALUE;int aggregateIndex = 0;Class<?> root = source;while (source != null && source != Object.class && remaining > 0 &&!hasPlainJavaAnnotationsOnly(source)) {R result = processor.doWithAggregate(context, aggregateIndex);if (result != null) {return result;}if (isFiltered(source, context, classFilter)) {continue;}Annotation[] declaredAnnotations =getDeclaredAnnotations(context, source, classFilter, true);if (relevant == null && declaredAnnotations.length > 0) {relevant = root.getAnnotations();remaining = relevant.length;}for (int i = 0; i < declaredAnnotations.length; i++) {if (declaredAnnotations[i] != null) {boolean isRelevant = false;for (int relevantIndex = 0; relevantIndex < relevant.length; relevantIndex++) {if (relevant[relevantIndex] != null &&declaredAnnotations[i].annotationType() == relevant[relevantIndex].annotationType()) {isRelevant = true;relevant[relevantIndex] = null;remaining--;break;}}if (!isRelevant) {declaredAnnotations[i] = null;}}}result = processor.doWithAnnotations(context, aggregateIndex, source, declaredAnnotations);if (result != null) {return result;}source = source.getSuperclass();aggregateIndex++;}return null;}@Nullableprivate static <C, R> R processClassHierarchy(C context, Class<?> source,AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter,boolean includeInterfaces, boolean includeEnclosing) {int[] aggregateIndex = new int[] {0};return processClassHierarchy(context, aggregateIndex, source, processor,classFilter, includeInterfaces, includeEnclosing);}@Nullableprivate static <C, R> R processClassHierarchy(C context, int[] aggregateIndex, Class<?> source,AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter,boolean includeInterfaces, boolean includeEnclosing) {R result = processor.doWithAggregate(context, aggregateIndex[0]);if (result != null) {return result;}if (hasPlainJavaAnnotationsOnly(source)) {return null;}Annotation[] annotations = getDeclaredAnnotations(context, source, classFilter, false);result = processor.doWithAnnotations(context, aggregateIndex[0], source, annotations);if (result != null) {return result;}aggregateIndex[0]++;if (includeInterfaces) {for (Class<?> interfaceType : source.getInterfaces()) {R interfacesResult = processClassHierarchy(context, aggregateIndex,interfaceType, processor, classFilter, true, includeEnclosing);if (interfacesResult != null) {return interfacesResult;}}}Class<?> superclass = source.getSuperclass();if (superclass != Object.class && superclass != null) {R superclassResult = processClassHierarchy(context, aggregateIndex,superclass, processor, classFilter, includeInterfaces, includeEnclosing);if (superclassResult != null) {return superclassResult;}}Class<?> enclosingClass = source.getEnclosingClass();if (includeEnclosing && enclosingClass != null) {R enclosingResult = processClassHierarchy(context, aggregateIndex,enclosingClass, processor, classFilter, includeInterfaces, true);if (enclosingResult != null) {return enclosingResult;}}return null;}掃描source為Method方法
@Nullable//根據查找策略掃描方法private static <C, R> R processMethod(C context, Method source,SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor,@Nullable BiPredicate<C, Class<?>> classFilter) {switch (searchStrategy) {case DIRECT:case INHERITED_ANNOTATIONS:return processMethodInheritedAnnotations(context, source, processor, classFilter);case SUPERCLASS:return processMethodHierarchy(context, new int[] {0}, source.getDeclaringClass(),processor, classFilter, source, false);case TYPE_HIERARCHY:case TYPE_HIERARCHY_AND_ENCLOSING_CLASSES:return processMethodHierarchy(context, new int[] {0}, source.getDeclaringClass(),processor, classFilter, source, true);}throw new IllegalStateException("Unsupported search strategy " + searchStrategy);}@Nullableprivate static <C, R> R processMethodInheritedAnnotations(C context, Method source,AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter) {R result = processor.doWithAggregate(context, 0);return (result != null ? result :processMethodAnnotations(context, 0, source, processor, classFilter));}@Nullableprivate static <C, R> R processMethodHierarchy(C context, int[] aggregateIndex,Class<?> sourceClass, AnnotationsProcessor<C, R> processor,@Nullable BiPredicate<C, Class<?>> classFilter, Method rootMethod,boolean includeInterfaces) {R result = processor.doWithAggregate(context, aggregateIndex[0]);if (result != null) {return result;}if (hasPlainJavaAnnotationsOnly(sourceClass)) {return null;}boolean calledProcessor = false;if (sourceClass == rootMethod.getDeclaringClass()) {result = processMethodAnnotations(context, aggregateIndex[0],rootMethod, processor, classFilter);calledProcessor = true;if (result != null) {return result;}}else {for (Method candidateMethod : getBaseTypeMethods(context, sourceClass, classFilter)) {if (candidateMethod != null && isOverride(rootMethod, candidateMethod)) {result = processMethodAnnotations(context, aggregateIndex[0],candidateMethod, processor, classFilter);calledProcessor = true;if (result != null) {return result;}}}}if (Modifier.isPrivate(rootMethod.getModifiers())) {return null;}if (calledProcessor) {aggregateIndex[0]++;}if (includeInterfaces) {for (Class<?> interfaceType : sourceClass.getInterfaces()) {R interfacesResult = processMethodHierarchy(context, aggregateIndex,interfaceType, processor, classFilter, rootMethod, true);if (interfacesResult != null) {return interfacesResult;}}}Class<?> superclass = sourceClass.getSuperclass();if (superclass != Object.class && superclass != null) {R superclassResult = processMethodHierarchy(context, aggregateIndex,superclass, processor, classFilter, rootMethod, includeInterfaces);if (superclassResult != null) {return superclassResult;}}return null;}輔助方法
//獲取基礎類型方法private static <C> Method[] getBaseTypeMethods(C context, Class<?> baseType, @Nullable BiPredicate<C, Class<?>> classFilter) {if (baseType == Object.class || hasPlainJavaAnnotationsOnly(baseType) ||isFiltered(baseType, context, classFilter)) {return NO_METHODS;}Method[] methods = baseTypeMethodsCache.get(baseType);if (methods == null) {boolean isInterface = baseType.isInterface();methods = isInterface ? baseType.getMethods() : ReflectionUtils.getDeclaredMethods(baseType);int cleared = 0;for (int i = 0; i < methods.length; i++) {if ((!isInterface && Modifier.isPrivate(methods[i].getModifiers())) ||hasPlainJavaAnnotationsOnly(methods[i]) ||getDeclaredAnnotations(methods[i], false).length == 0) {methods[i] = null;cleared++;}}if (cleared == methods.length) {methods = NO_METHODS;}baseTypeMethodsCache.put(baseType, methods);}return methods;}方法是否覆蓋private static boolean isOverride(Method rootMethod, Method candidateMethod) {return (!Modifier.isPrivate(candidateMethod.getModifiers()) &&candidateMethod.getName().equals(rootMethod.getName()) &&hasSameParameterTypes(rootMethod, candidateMethod));}方法是否具有相同參數類型private static boolean hasSameParameterTypes(Method rootMethod, Method candidateMethod) {if (candidateMethod.getParameterCount() != rootMethod.getParameterCount()) {return false;}Class<?>[] rootParameterTypes = rootMethod.getParameterTypes();Class<?>[] candidateParameterTypes = candidateMethod.getParameterTypes();if (Arrays.equals(candidateParameterTypes, rootParameterTypes)) {return true;}return hasSameGenericTypeParameters(rootMethod, candidateMethod,rootParameterTypes);}方法是否具有相同泛型類型private static boolean hasSameGenericTypeParameters(Method rootMethod, Method candidateMethod, Class<?>[] rootParameterTypes) {Class<?> sourceDeclaringClass = rootMethod.getDeclaringClass();Class<?> candidateDeclaringClass = candidateMethod.getDeclaringClass();if (!candidateDeclaringClass.isAssignableFrom(sourceDeclaringClass)) {return false;}for (int i = 0; i < rootParameterTypes.length; i++) {Class<?> resolvedParameterType = ResolvableType.forMethodParameter(candidateMethod, i, sourceDeclaringClass).resolve();if (rootParameterTypes[i] != resolvedParameterType) {return false;}}return true;}@Nullableprivate static <C, R> R processMethodAnnotations(C context, int aggregateIndex, Method source,AnnotationsProcessor<C, R> processor, @Nullable BiPredicate<C, Class<?>> classFilter) {Annotation[] annotations = getDeclaredAnnotations(context, source, classFilter, false);R result = processor.doWithAnnotations(context, aggregateIndex, source, annotations);if (result != null) {return result;}Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(source);if (bridgedMethod != source) {Annotation[] bridgedAnnotations = getDeclaredAnnotations(context, bridgedMethod, classFilter, true);for (int i = 0; i < bridgedAnnotations.length; i++) {if (ObjectUtils.containsElement(annotations, bridgedAnnotations[i])) {bridgedAnnotations[i] = null;}}return processor.doWithAnnotations(context, aggregateIndex, source, bridgedAnnotations);}return null;}private static <C, R> Annotation[] getDeclaredAnnotations(C context,AnnotatedElement source, @Nullable BiPredicate<C, Class<?>> classFilter, boolean copy) {if (source instanceof Class && isFiltered((Class<?>) source, context, classFilter)) {return NO_ANNOTATIONS;}if (source instanceof Method && isFiltered(((Method) source).getDeclaringClass(), context, classFilter)) {return NO_ANNOTATIONS;}return getDeclaredAnnotations(source, copy);}@SuppressWarnings("unchecked")@Nullablestatic <A extends Annotation> A getDeclaredAnnotation(AnnotatedElement source, Class<A> annotationType) {Annotation[] annotations = getDeclaredAnnotations(source, false);for (Annotation annotation : annotations) {if (annotation != null && annotationType == annotation.annotationType()) {return (A) annotation;}}return null;}static Annotation[] getDeclaredAnnotations(AnnotatedElement source, boolean defensive) {boolean cached = false;Annotation[] annotations = declaredAnnotationCache.get(source);if (annotations != null) {cached = true;}else {annotations = source.getDeclaredAnnotations();if (annotations.length != 0) {boolean allIgnored = true;for (int i = 0; i < annotations.length; i++) {Annotation annotation = annotations[i];if (isIgnorable(annotation.annotationType()) ||!AttributeMethods.forAnnotationType(annotation.annotationType()).isValid(annotation)) {annotations[i] = null;}else {allIgnored = false;}}annotations = (allIgnored ? NO_ANNOTATIONS : annotations);if (source instanceof Class || source instanceof Member) {declaredAnnotationCache.put(source, annotations);cached = true;}}}if (!defensive || annotations.length == 0 || !cached) {return annotations;}return annotations.clone();}private static <C> boolean isFiltered(Class<?> sourceClass, C context, @Nullable BiPredicate<C, Class<?>> classFilter) {return (classFilter != null && classFilter.test(context, sourceClass));}private static boolean isIgnorable(Class<?> annotationType) {return AnnotationFilter.PLAIN.matches(annotationType);}static boolean isKnownEmpty(AnnotatedElement source, SearchStrategy searchStrategy) {if (hasPlainJavaAnnotationsOnly(source)) {return true;}if (searchStrategy == SearchStrategy.DIRECT || isWithoutHierarchy(source, searchStrategy)) {if (source instanceof Method && ((Method) source).isBridge()) {return false;}return getDeclaredAnnotations(source, false).length == 0;}return false;}static boolean hasPlainJavaAnnotationsOnly(@Nullable Object annotatedElement) {if (annotatedElement instanceof Class) {return hasPlainJavaAnnotationsOnly((Class<?>) annotatedElement);}else if (annotatedElement instanceof Member) {return hasPlainJavaAnnotationsOnly(((Member) annotatedElement).getDeclaringClass());}else {return false;}}static boolean hasPlainJavaAnnotationsOnly(Class<?> type) {return (type.getName().startsWith("java.") || type == Ordered.class);}private static boolean isWithoutHierarchy(AnnotatedElement source, SearchStrategy searchStrategy) {if (source == Object.class) {return true;}if (source instanceof Class) {Class<?> sourceClass = (Class<?>) source;boolean noSuperTypes = (sourceClass.getSuperclass() == Object.class &&sourceClass.getInterfaces().length == 0);return (searchStrategy == SearchStrategy.TYPE_HIERARCHY_AND_ENCLOSING_CLASSES ? noSuperTypes &&sourceClass.getEnclosingClass() == null : noSuperTypes);}if (source instanceof Method) {Method sourceMethod = (Method) source;return (Modifier.isPrivate(sourceMethod.getModifiers()) ||isWithoutHierarchy(sourceMethod.getDeclaringClass(), searchStrategy));}return true;}?
MergedAnnotationSelector
提供在2個Annotation之間進行選擇的策略。
public interface MergedAnnotationSelector<A extends Annotation> {//是否最好的候選者default boolean isBestCandidate(MergedAnnotation<A> annotation) {return false;}//選擇MergedAnnotation<A> select(MergedAnnotation<A> existing, MergedAnnotation<A> candidate);}默認有2個實現類:
- 選擇最近策略
- 選擇直接注解策略
MergedAnnotationSelectors.Nearest
選擇距離較小。
private static class Nearest implements MergedAnnotationSelector<Annotation> {@Overridepublic boolean isBestCandidate(MergedAnnotation<Annotation> annotation) {return annotation.getDistance() == 0;}@Overridepublic MergedAnnotation<Annotation> select(MergedAnnotation<Annotation> existing, MergedAnnotation<Annotation> candidate) {if (candidate.getDistance() < existing.getDistance()) {return candidate;}return existing;}}MergedAnnotationSelectors.FirstDirectlyDeclared
選擇第一個直接注解的。
private static class FirstDirectlyDeclared implements MergedAnnotationSelector<Annotation> {@Overridepublic boolean isBestCandidate(MergedAnnotation<Annotation> annotation) {return annotation.getDistance() == 0;}@Overridepublic MergedAnnotation<Annotation> select(MergedAnnotation<Annotation> existing, MergedAnnotation<Annotation> candidate) {if (existing.getDistance() > 0 && candidate.getDistance() == 0) {return candidate;}return existing;}}AnnotationTypeMapping
提供一個注解在root注解上下文之間的映射信息。AnnotationTypeMapping的實例是由AnnotationTypeMappings創建的,創建的過程是根據注解的注釋體系從下往上進行的,上層實例的source指向下層實例,所有實例的root指向最下層的實例。
AnnotationTypeMapping.MirrorSets
MirrorSets是AnnotationTypeMapping一個內部類,是MirrorSet實例的容器。MirrorSet用于記錄本注解里屬性最終解析為同一個屬性方法的屬性信息集合,如果沒有為同一個屬性的別名,則不會產生MirrorSet實例,解析為同一個屬性方法的一組鏡像產生一個MirrorSet實例。
MirrorSet
class MirrorSet {//此MirrorSet被引用了多少次。private int size;/** 表示MirrorSet每次被引用的屬性的序號。注解鏡像屬性方法索引數組,size為屬性方法數量。數組下標代表找到的第n-1個鏡像方法,值為鏡像方法的索引。例如方法3或者4互相鏡像,則0:3,1:4,后續元素值都為-1.*/private final int[] indexes = new int[attributes.size()];//更新狀態,根據MirrorSets.assignedvoid update() {this.size = 0;Arrays.fill(this.indexes, -1);for (int i = 0; i < MirrorSets.this.assigned.length; i++) {if (MirrorSets.this.assigned[i] == this) {this.indexes[this.size] = i;this.size++;}}}//返回第一個不是默認值的方法的索引。<A> int resolve(@Nullable Object source, @Nullable A annotation,BiFunction<Method, Object, Object> valueExtractor) {int result = -1;Object lastValue = null;for (int i = 0; i < this.size; i++) {Method attribute = attributes.get(this.indexes[i]);//獲取到屬性的值。Object value = valueExtractor.apply(attribute, annotation);boolean isDefaultValue = (value == null ||isEquivalentToDefaultValue(attribute, value, valueExtractor));//如果屬性值不是默認值,并且與上一個值不相等,則繼續判斷。if (isDefaultValue || ObjectUtils.nullSafeEquals(lastValue, value)) {continue;}//上一個值不為null 并且 與上一個值不相等,則拋出異常。if (lastValue != null &&!ObjectUtils.nullSafeEquals(lastValue, value)) {String on = (source != null) ? " declared on " + source : "";throw new AnnotationConfigurationException(String.format("Different @AliasFor mirror values for annotation [%s]%s; attribute '%s' " +"and its alias '%s' are declared with values of [%s] and [%s].",getAnnotationType().getName(), on,attributes.get(result).getName(),attribute.getName(),ObjectUtils.nullSafeToString(lastValue),ObjectUtils.nullSafeToString(value)));}//更新result,并更新lastValue。result = this.indexes[i];lastValue = value;}return result;}}MirrorSets
class MirrorSets {private MirrorSet[] mirrorSets;//每個屬性方法引用的MirrorSet的index。未引用MirrorSet設置為-1.private final MirrorSet[] assigned;MirrorSets() {//size為屬性方法數量this.assigned = new MirrorSet[attributes.size()];this.mirrorSets = EMPTY_MIRROR_SETS;}/*** 對每個mapping,此方法會調用很多次。解析的最終屬性是同一個屬性方法的,作為一個鏡像組。* aliases: 每個屬性方法的所有層級的別名。*/void updateFrom(Collection<Method> aliases) {MirrorSet mirrorSet = null;//是別名的屬性的個數int size = 0;//上一個別名屬性的下標int last = -1;for (int i = 0; i < attributes.size(); i++) {Method attribute = attributes.get(i);//本注解定義的屬性是其他屬性的別名if (aliases.contains(attribute)) {size++;if (size > 1) {if (mirrorSet == null) {mirrorSet = new MirrorSet();this.assigned[last] = mirrorSet;}this.assigned[i] = mirrorSet;}last = i;}}if (mirrorSet != null) {mirrorSet.update();Set<MirrorSet> unique = new LinkedHashSet<>(Arrays.asList(this.assigned));unique.remove(null);this.mirrorSets = unique.toArray(EMPTY_MIRROR_SETS);}}int size() {return this.mirrorSets.length;}MirrorSet get(int index) {return this.mirrorSets[index];}@NullableMirrorSet getAssigned(int attributeIndex) {return this.assigned[attributeIndex];}/*** 返回本mapping每個屬性最終取值的屬性方法的序號 數組。* source:注解* annotation:注解實例* valueExtractor:* @return */int[] resolve(@Nullable Object source, @Nullable Object annotation,BiFunction<Method, Object, Object> valueExtractor) {int[] result = new int[attributes.size()];for (int i = 0; i < result.length; i++) {result[i] = i;}for (int i = 0; i < size(); i++) {MirrorSet mirrorSet = get(i);//返回mirrorSet中第一個不是默認值的屬性的序號。int resolved = mirrorSet.resolve(source, annotation, valueExtractor);//設置屬性方法的最終取值的屬性方法的序號。for (int j = 0; j < mirrorSet.size; j++) {result[mirrorSet.indexes[j]] = resolved;}}return result;}}?
屬性
final class AnnotationTypeMapping {private static final MirrorSet[] EMPTY_MIRROR_SETS = new MirrorSet[0];/***假設此AnnotationTypeMapping實例為 MA, 映射的為@A_A 注解。*/@Nullable//引起此注解被解析的注解。例如:@A_A注解了@A_ROOT,則此屬性指向了映射 @A_ROOT的AnnotationTypeMapping實例private final AnnotationTypeMapping source;//引起注解被解析的根注解。例如:@A_ROOT是解析的源頭,private final AnnotationTypeMapping root;//離root的距離。@A_A距離@A_ROOT 為1。private final int distance;//此mapping對應的注解類型,此處為A_Aprivate final Class<? extends Annotation> annotationType;//涉及到的注解類型列表。包括source的metaTypes 加上 annotationTypeprivate final List<Class<? extends Annotation>> metaTypes;@Nullable//注解類型實例。private final Annotation annotation;//注解的屬性方法列表包裝類。private final AttributeMethods attributes; /** *MirrorSet集合 *本注解里聲明的屬性,最終為同一個屬性的 別名 的屬性集合為一個MirrorSet */private final MirrorSets mirrorSets; //每個屬性在root中對應的同名的屬性方法的索引。與conventionMappings 的區別是,它是同名的屬性,不考慮別名。private final int[] aliasMappings; /**方便訪問屬性 的映射消息,如果在root中有別名,則優先獲取, */private final int[] conventionMappings; //與annotationValueSource是相匹配的,定義每個屬性最終從哪個注解的哪個屬性獲取值。private final int[] annotationValueMappings;private final AnnotationTypeMapping[] annotationValueSource;//存儲每個屬性的所有別名屬性方法(僅限于本注解定義中的屬性方法), // Key:AliasFor里定義的屬性方法,value為本注解內聲明的屬性方法。resolveAliasedForTargets方法中解析private final Map<Method, List<Method>> aliasedBy; //本注解聲明的所有屬性方法的所有別名集合。最后用于注解定義檢查然后會清空private final Set<Method> claimedAliases = new HashSet<>(); }構造過程
AnnotationTypeMapping(@Nullable AnnotationTypeMapping source,Class<? extends Annotation> annotationType, @Nullable Annotation annotation) {this.source = source;this.root = (source != null ? source.getRoot() : this);this.distance = (source == null ? 0 : source.getDistance() + 1);this.annotationType = annotationType;this.metaTypes = merge(source != null ? source.getMetaTypes() : null,annotationType);this.annotation = annotation;this.attributes = AttributeMethods.forAnnotationType(annotationType);this.mirrorSets = new MirrorSets();this.aliasMappings = filledIntArray(this.attributes.size());this.conventionMappings = filledIntArray(this.attributes.size());this.annotationValueMappings = filledIntArray(this.attributes.size());this.annotationValueSource = new AnnotationTypeMapping[this.attributes.size()];//返回每個屬性方法的所有別名(本注解聲明的屬性方法)。this.aliasedBy = resolveAliasedForTargets();processAliases();addConventionMappings();addConventionAnnotationValues();}生成別名信息(直接AliasFor)
//返回每個屬性方法的所有別名(本注解聲明的屬性方法)。//Key:AliasFor里定義的屬性方法,value為本注解內聲明的屬性方法。private Map<Method, List<Method>> resolveAliasedForTargets() {Map<Method, List<Method>> aliasedBy = new HashMap<>();for (int i = 0; i < this.attributes.size(); i++) {//聲明的屬性方法(作為value集合元素)。Method attribute = this.attributes.get(i);AliasFor aliasFor = AnnotationsScanner.getDeclaredAnnotation(attribute, AliasFor.class);if (aliasFor != null) {//最終解析的屬性方法(作為key)。Method target = resolveAliasTarget(attribute, aliasFor);aliasedBy.computeIfAbsent(target, key -> new ArrayList<>()).add(attribute);}}return Collections.unmodifiableMap(aliasedBy);}//解析屬性方法AliasFor的Method。private Method resolveAliasTarget(Method attribute, AliasFor aliasFor, boolean checkAliasPair) {if (StringUtils.hasText(aliasFor.value()) && StringUtils.hasText(aliasFor.attribute())) {throw new AnnotationConfigurationException(String.format("In @AliasFor declared on %s, attribute 'attribute' and its alias 'value' " +"are present with values of '%s' and '%s', but only one is permitted.",AttributeMethods.describe(attribute), aliasFor.attribute(),aliasFor.value()));}aliased注解。Class<? extends Annotation> targetAnnotation = aliasFor.annotation();//如果沒有設置annotation屬性,則表示是在本注解定義內。if (targetAnnotation == Annotation.class) {targetAnnotation = this.annotationType;}// aliased注解的屬性。通過AliasFor的attribute或者value屬性獲取,String targetAttributeName = aliasFor.attribute();if (!StringUtils.hasLength(targetAttributeName)) {targetAttributeName = aliasFor.value();}//如果attribute或者value都沒有值,則獲取aliased注解的屬性方法名稱。if (!StringUtils.hasLength(targetAttributeName)) {targetAttributeName = attribute.getName();}//獲取最終的aliased注解的屬性方法。Method target = AttributeMethods.forAnnotationType(targetAnnotation).get(targetAttributeName);........... 此處省略校驗邏輯return target;}全層級處理別名信息
//處理別名,生成MirrorSets,private void processAliases() {List<Method> aliases = new ArrayList<>();for (int i = 0; i < this.attributes.size(); i++) {aliases.clear();//本屬性方法的所有別名先加入。aliases.add(this.attributes.get(i));//再遞歸收集別名的別名,.......collectAliases(aliases);if (aliases.size() > 1) {processAliases(i, aliases);}}}//遞歸AnnotationTypeMapping鏈,收集別名(最終解析到此屬性方法的所有別名)。private void collectAliases(List<Method> aliases) {AnnotationTypeMapping mapping = this;while (mapping != null) {int size = aliases.size();for (int j = 0; j < size; j++) {List<Method> additional = mapping.aliasedBy.get(aliases.get(j));if (additional != null) {aliases.addAll(additional);}}mapping = mapping.source;}}/*** 對每個屬性方法,處理它的別名。* aliases:每個屬性方法的所有層級的別名。*/private void processAliases(int attributeIndex, List<Method> aliases) {//獲取root聲明的第一個別名屬性的index。-1表示root不存在此屬性方法的別名。int rootAttributeIndex = getFirstRootAttributeIndex(aliases);AnnotationTypeMapping mapping = this;while (mapping != null) {//在root中有別名,并且此mapping不是rootif (rootAttributeIndex != -1 && mapping != this.root) {for (int i = 0; i < mapping.attributes.size(); i++) {//如果別名中有此屬性,則對應的屬性index值為root的屬性的index。if (aliases.contains(mapping.attributes.get(i))) {mapping.aliasMappings[i] = rootAttributeIndex;}}}//更新mapping的mirrorSets。mapping.mirrorSets.updateFrom(aliases);//mapping聲明的屬性方法的別名集合。mapping.claimedAliases.addAll(aliases);if (mapping.annotation != null) {//返回本mapping每個屬性最終取值的屬性方法的序號 數組。int[] resolvedMirrors = mapping.mirrorSets.resolve(null,mapping.annotation, ReflectionUtils::invokeMethod);for (int i = 0; i < mapping.attributes.size(); i++) {//本屬性方法是別名,則設置注解值的最終來源(mppaing和屬性序號)if (aliases.contains(mapping.attributes.get(i))) {this.annotationValueMappings[attributeIndex] = resolvedMirrors[i];this.annotationValueSource[attributeIndex] = mapping;}}}mapping = mapping.source;}}生成方便訪問屬性的信息
//生成從root訪問屬性的方便屬性方法信息private void addConventionMappings() {if (this.distance == 0) {return;}AttributeMethods rootAttributes = this.root.getAttributes();//此時,元素值全為-1.int[] mappings = this.conventionMappings;for (int i = 0; i < mappings.length; i++) {String name = this.attributes.get(i).getName();MirrorSet mirrors = getMirrorSets().getAssigned(i);//root中是否存在同名的屬性int mapped = rootAttributes.indexOf(name);//root中存在同名的屬性,并且屬性名不為valueif (!MergedAnnotation.VALUE.equals(name) && mapped != -1) {//存儲root中的屬性方法index。mappings[i] = mapped;if (mirrors != null) {for (int j = 0; j < mirrors.size(); j++) {//同一屬性的所有別名,設置成一樣的root 屬性index。mappings[mirrors.getAttributeIndex(j)] = mapped;}}}}} //是更好的注解值獲取屬性方法(Value屬性優先,distance較小的優先)private boolean isBetterConventionAnnotationValue(int index, boolean isValueAttribute,AnnotationTypeMapping mapping) {//原來沒有獲取值的屬性方法。if (this.annotationValueMappings[index] == -1) {return true;}int existingDistance = this.annotationValueSource[index].distance;return !isValueAttribute && existingDistance > mapping.distance;}//更新各級AnnotationTypeMapping的annotationValueMappings和annotationValueSourceprivate void addConventionAnnotationValues() {for (int i = 0; i < this.attributes.size(); i++) {Method attribute = this.attributes.get(i);boolean isValueAttribute = MergedAnnotation.VALUE.equals(attribute.getName());AnnotationTypeMapping mapping = this;//在向root端(mapping.distance 比自己下的)遍歷。while (mapping != null && mapping.distance > 0) {int mapped = mapping.getAttributes().indexOf(attribute.getName());//有同名屬性if (mapped != -1 && isBetterConventionAnnotationValue(i, isValueAttribute, mapping)) {this.annotationValueMappings[i] = mapped;this.annotationValueSource[i] = mapping;}mapping = mapping.source;}}}?
AnnotationTypeMappings
?
?
AnnotationTypeMapping幫助理解示例
注解定義
@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @interface A_C {@AliasFor(value = "c2")String c1() default "A_C_1";@AliasFor(value = "c1")String c2() default "A_C_1";String c3() default "A_C_3";@AliasFor(value = "c5")String c4() default "A_C_4";@AliasFor(value = "c4")String c5() default "A_C_4";String c6() default "A_C_6";}@A_C @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @interface A_B {@AliasFor(value = "c2",annotation = A_C.class)String b1() default "A_B_1_2";@AliasFor(value = "c2",annotation = A_C.class)String b2() default "A_B_1_2";@AliasFor(value = "c2",annotation = A_C.class)String b3() default "A_B_1_2";String b4() default "A_B_4";}@A_B @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @interface A_A {@AliasFor(value = "c1",annotation = A_C.class)String a1() default "A_A_1";String a2() default "A_A_2";}@A_A @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) @interface A_ROOT {}@A_ROOT public class AnnotationUtilTest {public static void main(String[] args) {AnnotationAttributes a =AnnotatedElementUtils.findMergedAnnotationAttributes(AnnotationUtilTest.class,A_A.class,false,true);AnnotationAttributes b =AnnotatedElementUtils.findMergedAnnotationAttributes(AnnotationUtilTest.class,A_B.class,false,true);AnnotationAttributes c =AnnotatedElementUtils.findMergedAnnotationAttributes(AnnotationUtilTest.class,A_C.class,false,true);AnnotationAttributes root =AnnotatedElementUtils.findMergedAnnotationAttributes(AnnotationUtilTest.class,A_ROOT.class,false,true);System.out.println("x");} }注解使用
@A_ROOT public class AnnotationUtilTest {public static void main(String[] args) {AnnotationAttributes a =AnnotatedElementUtils.findMergedAnnotationAttributes(AnnotationUtilTest.class,A_A.class,false,true);AnnotationAttributes b =AnnotatedElementUtils.findMergedAnnotationAttributes(AnnotationUtilTest.class,A_B.class,false,true);AnnotationAttributes c =AnnotatedElementUtils.findMergedAnnotationAttributes(AnnotationUtilTest.class,A_C.class,false,true);AnnotationAttributes root =AnnotatedElementUtils.findMergedAnnotationAttributes(AnnotationUtilTest.class,A_ROOT.class,false,true);System.out.println("x");} }返回的AnnotationTypeMappings實例屬性
?獲取到AnnotationTypeMappings后,循環處理與requiredType相關的AnnotationTypeMapping ,獲取到MergedAnnotation,選擇一個最合適的MergedAnnotation
AnnotationTypeMappings mappings = AnnotationTypeMappings.forAnnotationType(annotation.annotationType(), annotationFilter);for (int i = 0; i < mappings.size(); i++) {AnnotationTypeMapping mapping = mappings.get(i);if (isMappingForType(mapping, annotationFilter, this.requiredType)) {MergedAnnotation<A> candidate = TypeMappedAnnotation.createIfPossible(mapping, source, annotation, aggregateIndex, IntrospectionFailureLogger.INFO);if (candidate != null && (this.predicate == null || this.predicate.test(candidate))) {if (this.selector.isBestCandidate(candidate)) {return candidate;}updateLastResult(candidate);}}} private static boolean isMappingForType(AnnotationTypeMapping mapping,AnnotationFilter annotationFilter, @Nullable Object requiredType) {Class<? extends Annotation> actualType = mapping.getAnnotationType(); //未過濾掉并且(requiredType 為空 或者是同一個類型,或者名稱相同)return (!annotationFilter.matches(actualType) &&(requiredType == null || actualType == requiredType || actualType.getName().equals(requiredType)));}?
總結
以上是生活随笔為你收集整理的Spring注解编程基石(四)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: xxl-job 2.1.1执行器源码解读
- 下一篇: Spring注解编程基石(三)