Skip to content

Latest commit

 

History

History
489 lines (404 loc) · 15.9 KB

Spring-AnnotationUtils.md

File metadata and controls

489 lines (404 loc) · 15.9 KB

Spring AnnotationUtils

  • Author: HuiFer
  • 源码阅读仓库: SourceHot-Spring
  • org.springframework.core.annotation.AnnotationUtils提供了注解相关的方法
    1. getAnnotation: 获取注解
    2. findAnnotation: 寻找注解
    3. getValue: 获取属性值
    4. getDefaultValue: 获取默认值

getAnnotation

  • 测试用例如下
@TestpublicvoidfindMethodAnnotationOnLeaf() throwsException { Methodm = Leaf.class.getMethod("annotatedOnLeaf"); assertNotNull(m.getAnnotation(Order.class)); assertNotNull(getAnnotation(m, Order.class)); assertNotNull(findAnnotation(m, Order.class)); }
  • org.springframework.core.annotation.AnnotationUtils.getAnnotation(java.lang.reflect.Method, java.lang.Class<A>)
/** * Get a single {@link Annotation} of {@code annotationType} from the * supplied {@link Method}, where the annotation is either <em>present</em> * or <em>meta-present</em> on the method. * <p>Correctly handles bridge {@link Method Methods} generated by the compiler. * <p>Note that this method supports only a single level of meta-annotations. * For support for arbitrary levels of meta-annotations, use * {@link #findAnnotation(Method, Class)} instead. * * @param method the method to look for annotations on * 被检查的函数 * @param annotationType the annotation type to look for * 需要检测的注解类型 * @return the first matching annotation, or {@code null} if not found * @see org.springframework.core.BridgeMethodResolver#findBridgedMethod(Method) * @see #getAnnotation(AnnotatedElement, Class) */@Nullablepublicstatic <AextendsAnnotation> AgetAnnotation(Methodmethod, Class<A> annotationType) { // 函数MethodresolvedMethod = BridgeMethodResolver.findBridgedMethod(method); // 强制转换returngetAnnotation((AnnotatedElement) resolvedMethod, annotationType); }
  • method

image-20200116085344737

  • annotationType

image-20200116085423073

@Nullablepublicstatic <AextendsAnnotation> AgetAnnotation(AnnotatedElementannotatedElement, Class<A> annotationType) { try { // 获取注解Aannotation = annotatedElement.getAnnotation(annotationType); if (annotation == null) { for (AnnotationmetaAnn : annotatedElement.getAnnotations()) { annotation = metaAnn.annotationType().getAnnotation(annotationType); if (annotation != null) { break; } } } return (annotation != null ? synthesizeAnnotation(annotation, annotatedElement) : null); } catch (Throwableex) { handleIntrospectionFailure(annotatedElement, ex); returnnull; } }
  • org.springframework.core.annotation.AnnotationUtils.synthesizeAnnotation(A, java.lang.reflect.AnnotatedElement)
publicstatic <AextendsAnnotation> AsynthesizeAnnotation( Aannotation, @NullableAnnotatedElementannotatedElement) { returnsynthesizeAnnotation(annotation, (Object) annotatedElement); }
/** * 注解是否存在别名,没有直接返回 * * @param annotation 注解 * @param annotatedElement 函数 * @param <A> * @return */@SuppressWarnings("unchecked") static <AextendsAnnotation> AsynthesizeAnnotation(Aannotation, @NullableObjectannotatedElement) { if (annotationinstanceofSynthesizedAnnotation || hasPlainJavaAnnotationsOnly(annotatedElement)) { returnannotation; } // 具体的注解Class<? extendsAnnotation> annotationType = annotation.annotationType(); if (!isSynthesizable(annotationType)) { returnannotation; } DefaultAnnotationAttributeExtractorattributeExtractor = newDefaultAnnotationAttributeExtractor(annotation, annotatedElement); InvocationHandlerhandler = newSynthesizedAnnotationInvocationHandler(attributeExtractor); // Can always expose Spring's SynthesizedAnnotation marker since we explicitly check for a// synthesizable annotation before (which needs to declare @AliasFor from the same package)Class<?>[] exposedInterfaces = newClass<?>[]{annotationType, SynthesizedAnnotation.class}; return (A) Proxy.newProxyInstance(annotation.getClass().getClassLoader(), exposedInterfaces, handler); }

-org.springframework.core.annotation.AnnotationUtils.isSynthesizable

@SuppressWarnings("unchecked") privatestaticbooleanisSynthesizable(Class<? extendsAnnotation> annotationType) { if (hasPlainJavaAnnotationsOnly(annotationType)) { returnfalse; } // 从缓存中获取当前注解,不存在nullBooleansynthesizable = synthesizableCache.get(annotationType); if (synthesizable != null) { returnsynthesizable; } synthesizable = Boolean.FALSE; for (Methodattribute : getAttributeMethods(annotationType)) { if (!getAttributeAliasNames(attribute).isEmpty()) { synthesizable = Boolean.TRUE; break; } // 获取返回值类型Class<?> returnType = attribute.getReturnType(); // 根据返回值做不同处理if (Annotation[].class.isAssignableFrom(returnType)) { Class<? extendsAnnotation> nestedAnnotationType = (Class<? extendsAnnotation>) returnType.getComponentType(); if (isSynthesizable(nestedAnnotationType)) { synthesizable = Boolean.TRUE; break; } } elseif (Annotation.class.isAssignableFrom(returnType)) { Class<? extendsAnnotation> nestedAnnotationType = (Class<? extendsAnnotation>) returnType; if (isSynthesizable(nestedAnnotationType)) { synthesizable = Boolean.TRUE; break; } } } synthesizableCache.put(annotationType, synthesizable); returnsynthesizable; }
  • org.springframework.core.annotation.AnnotationUtils#getAttributeMethods
staticList<Method> getAttributeMethods(Class<? extendsAnnotation> annotationType) { List<Method> methods = attributeMethodsCache.get(annotationType); if (methods != null) { returnmethods; } methods = newArrayList<>(); // annotationType.getDeclaredMethods() 获取注解中的方法for (Methodmethod : annotationType.getDeclaredMethods()) { if (isAttributeMethod(method)) { ReflectionUtils.makeAccessible(method); methods.add(method); } } // 缓存 key:注解,value:函数列表attributeMethodsCache.put(annotationType, methods); // 函数列表returnmethods; }
  • org.springframework.core.annotation.AnnotationUtils#isAttributeMethod
/** * Determine if the supplied {@code method} is an annotation attribute method. * <p> * 做3个判断 * <ol> * <li>函数不为空(method != null)</li> * <li>参数列表是不是空(method.getParameterCount() == 0)</li> * <li>返回类型不是void(method.getReturnType() != void.class)</li> * </ol> * * @param method the method to check * @return {@code true} if the method is an attribute method * @since 4.2 */staticbooleanisAttributeMethod(@NullableMethodmethod) { return (method != null && method.getParameterCount() == 0 && method.getReturnType() !=void.class); }
  • org.springframework.util.ReflectionUtils#makeAccessible(java.lang.reflect.Method)
@SuppressWarnings("deprecation") // on JDK 9publicstaticvoidmakeAccessible(Methodmethod) { // 1. 方法修饰符是不是public// 2. 注解是不是public// 3. 是否重写if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) && !method.isAccessible()) { method.setAccessible(true); } }

处理结果

image-20200116085726577

image-20200116085737632

处理结果和 Order 定义相同

@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD}) @Documentedpublic @interface Order { /** * The order value. * <p>Default is {@link Ordered#LOWEST_PRECEDENCE}. * * 启动顺序,默认integer最大值 * @see Ordered#getOrder() */intvalue() defaultOrdered.LOWEST_PRECEDENCE; }

最终返回

image-20200116085927359

findAnnotation

  • org.springframework.core.annotation.AnnotationUtils#findAnnotation(java.lang.reflect.Method, java.lang.Class<A>)
@SuppressWarnings("unchecked") @Nullablepublicstatic <AextendsAnnotation> AfindAnnotation(Methodmethod, @NullableClass<A> annotationType) { Assert.notNull(method, "Method must not be null"); if (annotationType == null) { returnnull; } // 创建注解缓存,key:被扫描的函数,value:注解AnnotationCacheKeycacheKey = newAnnotationCacheKey(method, annotationType); // 从findAnnotationCache获取缓存Aresult = (A) findAnnotationCache.get(cacheKey); if (result == null) { MethodresolvedMethod = BridgeMethodResolver.findBridgedMethod(method); // 寻找注解result = findAnnotation((AnnotatedElement) resolvedMethod, annotationType); if (result == null) { result = searchOnInterfaces(method, annotationType, method.getDeclaringClass().getInterfaces()); } Class<?> clazz = method.getDeclaringClass(); while (result == null) { clazz = clazz.getSuperclass(); if (clazz == null || clazz == Object.class) { break; } Set<Method> annotatedMethods = getAnnotatedMethodsInBaseType(clazz); if (!annotatedMethods.isEmpty()) { for (MethodannotatedMethod : annotatedMethods) { if (isOverride(method, annotatedMethod)) { MethodresolvedSuperMethod = BridgeMethodResolver.findBridgedMethod(annotatedMethod); result = findAnnotation((AnnotatedElement) resolvedSuperMethod, annotationType); if (result != null) { break; } } } } if (result == null) { result = searchOnInterfaces(method, annotationType, clazz.getInterfaces()); } } if (result != null) { // 处理注解result = synthesizeAnnotation(result, method); // 添加缓存findAnnotationCache.put(cacheKey, result); } } // 返回returnresult; }
  • org.springframework.core.annotation.AnnotationUtils.AnnotationCacheKey
privatestaticfinalclassAnnotationCacheKeyimplementsComparable<AnnotationCacheKey> { /** * 带有注解的函数或者类 */privatefinalAnnotatedElementelement; /** * 注解 */privatefinalClass<? extendsAnnotation> annotationType; publicAnnotationCacheKey(AnnotatedElementelement, Class<? extendsAnnotation> annotationType) { this.element = element; this.annotationType = annotationType; } }
  • org.springframework.core.annotation.AnnotationUtils#findAnnotation(java.lang.reflect.AnnotatedElement, java.lang.Class<A>)
@Nullablepublicstatic <AextendsAnnotation> AfindAnnotation( AnnotatedElementannotatedElement, @NullableClass<A> annotationType) { // 注解类型不为空if (annotationType == null) { returnnull; } // Do NOT store result in the findAnnotationCache since doing so could break// findAnnotation(Class, Class) and findAnnotation(Method, Class).// 寻找注解Aann = findAnnotation(annotatedElement, annotationType, newHashSet<>()); return (ann != null ? synthesizeAnnotation(ann, annotatedElement) : null); }
  • org.springframework.core.annotation.AnnotationUtils#findAnnotation(java.lang.reflect.AnnotatedElement, java.lang.Class<A>, java.util.Set<java.lang.annotation.Annotation>)
@Nullableprivatestatic <AextendsAnnotation> AfindAnnotation( AnnotatedElementannotatedElement, Class<A> annotationType, Set<Annotation> visited) { try { // 直接获取注解Aannotation = annotatedElement.getDeclaredAnnotation(annotationType); if (annotation != null) { returnannotation; } // 多级注解for (AnnotationdeclaredAnn : getDeclaredAnnotations(annotatedElement)) { Class<? extendsAnnotation> declaredType = declaredAnn.annotationType(); // 注解是否 由java.lang.annotation提供if (!isInJavaLangAnnotationPackage(declaredType) && visited.add(declaredAnn)) { annotation = findAnnotation((AnnotatedElement) declaredType, annotationType, visited); if (annotation != null) { returnannotation; } } } } catch (Throwableex) { handleIntrospectionFailure(annotatedElement, ex); } returnnull; }

image-20200116092259944

  • synthesizeAnnotation方法就不再重复一遍了可以看上文

getValue

  • 测试用例
@TestpublicvoidgetValueFromAnnotation() throwsException { Methodmethod = SimpleFoo.class.getMethod("something", Object.class); Orderorder = findAnnotation(method, Order.class); assertEquals(1, getValue(order, VALUE)); assertEquals(1, getValue(order)); }
  • org.springframework.core.annotation.AnnotationUtils#getValue(java.lang.annotation.Annotation, java.lang.String)
@NullablepublicstaticObjectgetValue(@NullableAnnotationannotation, @NullableStringattributeName) { if (annotation == null || !StringUtils.hasText(attributeName)) { returnnull; } try { // 根据attributeName获取注解对应函数Methodmethod = annotation.annotationType().getDeclaredMethod(attributeName); ReflectionUtils.makeAccessible(method); // 反射执行方法returnmethod.invoke(annotation); } catch (NoSuchMethodExceptionex) { returnnull; } catch (InvocationTargetExceptionex) { rethrowAnnotationConfigurationException(ex.getTargetException()); thrownewIllegalStateException("Could not obtain value for annotation attribute '" + attributeName + "' in " + annotation, ex); } catch (Throwableex) { handleIntrospectionFailure(annotation.getClass(), ex); returnnull; } }
@NullablepublicstaticObjectgetValue(Annotationannotation) { returngetValue(annotation, VALUE); }

getDefaultValue

  • org.springframework.core.annotation.AnnotationUtils#getDefaultValue(java.lang.annotation.Annotation)
@NullablepublicstaticObjectgetDefaultValue(Annotationannotation) { returngetDefaultValue(annotation, VALUE); }
@NullablepublicstaticObjectgetDefaultValue( @NullableClass<? extendsAnnotation> annotationType, @NullableStringattributeName) { if (annotationType == null || !StringUtils.hasText(attributeName)) { returnnull; } try { // 直接获取defaultValuereturnannotationType.getDeclaredMethod(attributeName).getDefaultValue(); } catch (Throwableex) { handleIntrospectionFailure(annotationType, ex); returnnull; } }
close