Spring 元信息
- Author: HuiFer
- 源码阅读仓库: SourceHot-Spring
ClassMetadata
public interface ClassMetadata {/*** 类名*/String getClassName();/*** 是否是接口*/boolean isInterface();/*** 是否是注解*/boolean isAnnotation();/*** 是否是超类*/boolean isAbstract();/*** 是否允许创建,实例化*/default boolean isConcrete() {return !(isInterface() || isAbstract());}/*** 是否有final修饰*/boolean isFinal();/*** 是否独立*/boolean isIndependent();/*** 是否有内部类*/default boolean hasEnclosingClass() {return (getEnclosingClassName() != null);}/*** 是否是基础类*/@NullableString getEnclosingClassName();/*** 是否有父类*/default boolean hasSuperClass() {return (getSuperClassName() != null);}/*** 父类名称*/@NullableString getSuperClassName();/*** 实现类名称列表*/String[] getInterfaceNames();/*** 成员列表* @since 3.1*/String[] getMemberClassNames();}

AnnotatedTypeMetadata
public interface AnnotatedTypeMetadata {/*** 获取所有注解*/MergedAnnotations getAnnotations();/*** 是否有注解*/default boolean isAnnotated(String annotationName) {return getAnnotations().isPresent(annotationName);}/*** 获取注解的属性*/@Nullabledefault Map<String, Object> getAnnotationAttributes(String annotationName) {return getAnnotationAttributes(annotationName, false);}// 省略其他}
AnnotationMetadata
public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata {/*** 获取注解名称,全类名*/default Set<String> getAnnotationTypes() {return getAnnotations().stream().filter(MergedAnnotation::isDirectlyPresent).map(annotation -> annotation.getType().getName()).collect(Collectors.toCollection(LinkedHashSet::new));}/*** 注解全类名*/default Set<String> getMetaAnnotationTypes(String annotationName) {MergedAnnotation<?> annotation = getAnnotations().get(annotationName, MergedAnnotation::isDirectlyPresent);if (!annotation.isPresent()) {return Collections.emptySet();}return MergedAnnotations.from(annotation.getType(), SearchStrategy.INHERITED_ANNOTATIONS).stream().map(mergedAnnotation -> mergedAnnotation.getType().getName()).collect(Collectors.toCollection(LinkedHashSet::new));}/*** 是否包含某个注解*/default boolean hasAnnotation(String annotationName) {return getAnnotations().isDirectlyPresent(annotationName);}/*** 是否被某个注解标记过*/default boolean hasMetaAnnotation(String metaAnnotationName) {return getAnnotations().get(metaAnnotationName,MergedAnnotation::isMetaPresent).isPresent();}/*** 是否有注解,类里面有一个注解就返回true*/default boolean hasAnnotatedMethods(String annotationName) {return !getAnnotatedMethods(annotationName).isEmpty();}/*** 获取包含注解的方法*/Set<MethodMetadata> getAnnotatedMethods(String annotationName);/*** 通过反射创建一个注解的元信息*/static AnnotationMetadata introspect(Class<?> type) {return StandardAnnotationMetadata.from(type);}}
MethodMetadata
public interface MethodMetadata extends AnnotatedTypeMetadata {/*** 方法名称*/String getMethodName();/*** 方法全路径*/String getDeclaringClassName();/*** 返回值类型*/String getReturnTypeName();/*** 是不是abstrac修饰*/boolean isAbstract();/*** 是否 static 修饰*/boolean isStatic();/*** 是否 final 修饰*/boolean isFinal();/*** 是否重载*/boolean isOverridable();}
MetadataReader
public interface MetadataReader {/*** Return the resource reference for the class file.** 获取资源*/Resource getResource();/*** Read basic class metadata for the underlying class.* 获取类的元信息*/ClassMetadata getClassMetadata();/*** Read full annotation metadata for the underlying class,* including metadata for annotated methods.** 获取注解的元信息*/AnnotationMetadata getAnnotationMetadata();}
MetadataReaderFactory
- 用来创建 MetadataReader
public interface MetadataReaderFactory {/*** Obtain a MetadataReader for the given class name.* @param className the class name (to be resolved to a ".class" file)* @return a holder for the ClassReader instance (never {@code null})* @throws IOException in case of I/O failure*/MetadataReader getMetadataReader(String className) throws IOException;/*** Obtain a MetadataReader for the given resource.* @param resource the resource (pointing to a ".class" file)* @return a holder for the ClassReader instance (never {@code null})* @throws IOException in case of I/O failure*/MetadataReader getMetadataReader(Resource resource) throws IOException;}
- 接口解释的差不多了.接下来看一些实现
StandardClassMetadata
通过 JAVA 反射来获取类的元信息
这个类采用的方式是 Java class 的方法,通过构造方法来填写一个 Class 对象. 之后使用这个对象的方法
public class StandardClassMetadata implements ClassMetadata {private final Class<?> introspectedClass;@Deprecatedpublic StandardClassMetadata(Class<?> introspectedClass) {Assert.notNull(introspectedClass, "Class must not be null");this.introspectedClass = introspectedClass;}/*** Return the underlying Class.*/public final Class<?> getIntrospectedClass() {return this.introspectedClass;}@Overridepublic String getClassName() {return this.introspectedClass.getName();}@Overridepublic boolean isInterface() {return this.introspectedClass.isInterface();}@Overridepublic boolean isAnnotation() {return this.introspectedClass.isAnnotation();}@Overridepublic boolean isAbstract() {return Modifier.isAbstract(this.introspectedClass.getModifiers());}@Overridepublic boolean isFinal() {return Modifier.isFinal(this.introspectedClass.getModifiers());}@Overridepublic boolean isIndependent() {return (!hasEnclosingClass() ||(this.introspectedClass.getDeclaringClass() != null &&Modifier.isStatic(this.introspectedClass.getModifiers())));}@Override@Nullablepublic String getEnclosingClassName() {Class<?> enclosingClass = this.introspectedClass.getEnclosingClass();return (enclosingClass != null ? enclosingClass.getName() : null);}@Override@Nullablepublic String getSuperClassName() {Class<?> superClass = this.introspectedClass.getSuperclass();return (superClass != null ? superClass.getName() : null);}@Overridepublic String[] getInterfaceNames() {Class<?>[] ifcs = this.introspectedClass.getInterfaces();String[] ifcNames = new String[ifcs.length];for (int i = 0; i < ifcs.length; i++) {ifcNames[i] = ifcs[i].getName();}return ifcNames;}@Overridepublic String[] getMemberClassNames() {LinkedHashSet<String> memberClassNames = new LinkedHashSet<>(4);for (Class<?> nestedClass : this.introspectedClass.getDeclaredClasses()) {memberClassNames.add(nestedClass.getName());}return StringUtils.toStringArray(memberClassNames);}}
StandardMethodMetadata
- 通过 java 反射获取方法的元信息
- 构造方法传递一个 method
- 如果这个方法有注解,会进行注解的解析
public class StandardMethodMetadata implements MethodMetadata {private final Method introspectedMethod;private final boolean nestedAnnotationsAsMap;private final MergedAnnotations mergedAnnotations;@Deprecatedpublic StandardMethodMetadata(Method introspectedMethod) {this(introspectedMethod, false);}@Deprecatedpublic StandardMethodMetadata(Method introspectedMethod, boolean nestedAnnotationsAsMap) {Assert.notNull(introspectedMethod, "Method must not be null");this.introspectedMethod = introspectedMethod;this.nestedAnnotationsAsMap = nestedAnnotationsAsMap;this.mergedAnnotations = MergedAnnotations.from(introspectedMethod, SearchStrategy.DIRECT, RepeatableContainers.none());}@Overridepublic MergedAnnotations getAnnotations() {return this.mergedAnnotations;}/*** Return the underlying Method.*/public final Method getIntrospectedMethod() {return this.introspectedMethod;}@Overridepublic String getMethodName() {return this.introspectedMethod.getName();}@Overridepublic String getDeclaringClassName() {return this.introspectedMethod.getDeclaringClass().getName();}@Overridepublic String getReturnTypeName() {return this.introspectedMethod.getReturnType().getName();}@Overridepublic boolean isAbstract() {return Modifier.isAbstract(this.introspectedMethod.getModifiers());}@Overridepublic boolean isStatic() {return Modifier.isStatic(this.introspectedMethod.getModifiers());}@Overridepublic boolean isFinal() {return Modifier.isFinal(this.introspectedMethod.getModifiers());}@Overridepublic boolean isOverridable() {return !isStatic() && !isFinal() && !isPrivate();}private boolean isPrivate() {return Modifier.isPrivate(this.introspectedMethod.getModifiers());}@Override@Nullablepublic Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {if (this.nestedAnnotationsAsMap) {return MethodMetadata.super.getAnnotationAttributes(annotationName, classValuesAsString);}return AnnotatedElementUtils.getMergedAnnotationAttributes(this.introspectedMethod,annotationName, classValuesAsString, false);}/*** 获取所有注解的信息*/@Override@Nullablepublic MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString) {if (this.nestedAnnotationsAsMap) {return MethodMetadata.super.getAllAnnotationAttributes(annotationName, classValuesAsString);}return AnnotatedElementUtils.getAllAnnotationAttributes(this.introspectedMethod,annotationName, classValuesAsString, false);}}
StandardAnnotationMetadata
StandardAnnotationMetadata 是 StandardClassMetadata 的子类
还是一个基于 JAVA 反射做的一个类
获取注解属性 map
@Override@Nullablepublic Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {if (this.nestedAnnotationsAsMap) {return AnnotationMetadata.super.getAnnotationAttributes(annotationName, classValuesAsString);}return AnnotatedElementUtils.getMergedAnnotationAttributes(getIntrospectedClass(), annotationName, classValuesAsString, false);}
org.springframework.core.annotation.AnnotatedElementUtils#getMergedAnnotationAttributes(java.lang.reflect.AnnotatedElement, java.lang.String, boolean, boolean)org.springframework.core.annotation.AnnotatedElementUtils#getAnnotationAttributesorg.springframework.core.annotation.MergedAnnotation#asAnnotationAttributes
@Nullablepublic static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element,String annotationName, boolean classValuesAsString, boolean nestedAnnotationsAsMap) {MergedAnnotation<?> mergedAnnotation = getAnnotations(element).get(annotationName, null, MergedAnnotationSelectors.firstDirectlyDeclared());return getAnnotationAttributes(mergedAnnotation, classValuesAsString, nestedAnnotationsAsMap);}
- 查看这个方法的源码借助测试类
org.springframework.core.annotation.AnnotatedElementUtilsTests#getMergedAnnotationAttributesOnClassWithLocalAnnotation - getAnnotations() 方法
getAnnotations
org.springframework.core.annotation.MergedAnnotations#from(java.lang.reflect.AnnotatedElement, org.springframework.core.annotation.MergedAnnotations.SearchStrategy, org.springframework.core.annotation.RepeatableContainers)org.springframework.core.annotation.TypeMappedAnnotations#from(java.lang.reflect.AnnotatedElement, org.springframework.core.annotation.MergedAnnotations.SearchStrategy, org.springframework.core.annotation.RepeatableContainers, org.springframework.core.annotation.AnnotationFilter)
最终我们找到的代码如下
static MergedAnnotations from(AnnotatedElement element, SearchStrategy searchStrategy,RepeatableContainers repeatableContainers, AnnotationFilter annotationFilter) {if (AnnotationsScanner.isKnownEmpty(element, searchStrategy)) {return NONE;}return new TypeMappedAnnotations(element, searchStrategy, repeatableContainers, annotationFilter);}
- 判断是否为空. 为空返回 None,不会为空构造出一个对象 org.springframework.core.annotation.TypeMappedAnnotations
MergedAnnotations
public interface MergedAnnotations extends Iterable<MergedAnnotation<Annotation>> {//确定注解是否存在<A extends Annotation> boolean isPresent(Class<A> annotationType);//注解是否直接存在<A extends Annotation> boolean isDirectlyPresent(Class<A> annotationType);// 获取匹配的注解<A extends Annotation> MergedAnnotation<A> get(Class<A> annotationType);// 省略其他}
这个接口中还有两个方法
of将多个MergedAnnotations合并from将多个注解合并
SearchStrategy
enum SearchStrategy {/*** Find only directly declared annotations, without considering* {@link Inherited @Inherited} annotations and without searching* superclasses or implemented interfaces.** 直接查找*/DIRECT,/*** Find all directly declared annotations as well as any* {@link Inherited @Inherited} superclass annotations. This strategy* is only really useful when used with {@link Class} types since the* {@link Inherited @Inherited} annotation is ignored for all other* {@linkplain AnnotatedElement annotated elements}. This strategy does* not search implemented interfaces.** 继承查找*/INHERITED_ANNOTATIONS,/*** Find all directly declared and superclass annotations. This strategy* is similar to {@link #INHERITED_ANNOTATIONS} except the annotations* do not need to be meta-annotated with {@link Inherited @Inherited}.* This strategy does not search implemented interfaces.* 查找当前类和父类的注解*/SUPERCLASS,/*** Perform a full search of the entire type hierarchy, including* superclasses and implemented interfaces. Superclass annotations do* not need to be meta-annotated with {@link Inherited @Inherited}.*/TYPE_HIERARCHY,/*** Perform a full search of the entire type hierarchy on the source* <em>and</em> any enclosing classes. This strategy is similar to* {@link #TYPE_HIERARCHY} except that {@linkplain Class#getEnclosingClass()* enclosing classes} are also searched. Superclass annotations do not* need to be meta-annotated with {@link Inherited @Inherited}. When* searching a {@link Method} source, this strategy is identical to* {@link #TYPE_HIERARCHY}.*/TYPE_HIERARCHY_AND_ENCLOSING_CLASSES}
org.springframework.core.annotation.TypeMappedAnnotations#get(java.lang.String, java.util.function.Predicate<? super org.springframework.core.annotation.MergedAnnotation<A>>, org.springframework.core.annotation.MergedAnnotationSelector<A>)
@Overridepublic <A extends Annotation> MergedAnnotation<A> get(String annotationType,@Nullable Predicate<? super MergedAnnotation<A>> predicate,@Nullable MergedAnnotationSelector<A> selector) {// 匹配校验if (this.annotationFilter.matches(annotationType)) {return MergedAnnotation.missing();}MergedAnnotation<A> result = scan(annotationType,new MergedAnnotationFinder<>(annotationType, predicate, selector));return (result != null ? result : MergedAnnotation.missing());}
Scan
org.springframework.core.annotation.AnnotationsScanner#scan(C, java.lang.reflect.AnnotatedElement, org.springframework.core.annotation.MergedAnnotations.SearchStrategy, org.springframework.core.annotation.AnnotationsProcessor<C,R>, java.util.function.BiPredicate<C,java.lang.Class<?>>)
@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);}
在这个里面重点关注PROCESS方法
@Nullableprivate static <C, R> R process(C context, AnnotatedElement source,SearchStrategy searchStrategy, AnnotationsProcessor<C, R> processor,@Nullable BiPredicate<C, Class<?>> classFilter) {if (source instanceof Class) {return processClass(context, (Class<?>) source, searchStrategy, processor, classFilter);}if (source instanceof Method) {return processMethod(context, (Method) source, searchStrategy, processor, classFilter);}return processElement(context, source, processor, classFilter);}
测试类
@Transactional("TxConfig")static class TxConfig {}
显然这是一个类他会走processClass方法
- 根据扫描方式进行扫描
@Nullableprivate 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);}
- 扫描的形式就不贴出完整代码了
finish就包装一下返回.
此时
org.springframework.core.annotation.AnnotatedElementUtils#getMergedAnnotationAttributes(java.lang.reflect.AnnotatedElement, java.lang.String, boolean, boolean)这个方法走到了最后一步org.springframework.core.annotation.AnnotatedElementUtils#getAnnotationAttributes最后的组装 map 方法
org.springframework.core.annotation.TypeMappedAnnotation#asMap(java.util.function.Function<org.springframework.core.annotation.MergedAnnotation<?>,T>, org.springframework.core.annotation.MergedAnnotation.Adapt...)
@Overridepublic AnnotationAttributes asAnnotationAttributes(Adapt... adaptations) {return asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType()), adaptations);}
@Overridepublic <T extends Map<String, Object>> T asMap(Function<MergedAnnotation<?>, T> factory, Adapt... adaptations) {T map = factory.apply(this);Assert.state(map != null, "Factory used to create MergedAnnotation Map must not return null");AttributeMethods attributes = this.mapping.getAttributes();for (int i = 0; i < attributes.size(); i++) {Method attribute = attributes.get(i);Object value = (isFiltered(attribute.getName()) ? null :getValue(i, getTypeForMapOptions(attribute, adaptations)));if (value != null) {map.put(attribute.getName(),adaptValueForMapOptions(attribute, value, map.getClass(), factory, adaptations));}}return map;}
获取属性列表,循环, 放入 map 返回.
map
key: 注解的函数
value: 函数对应的值
@Transactional("TxConfig")
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.TYPE, ElementType.METHOD})@Inherited@interface Transactional {String value() default "";String qualifier() default "transactionManager";boolean readOnly() default false;}
如果是上面这样的结构那么返回值为
value:TxConfigqulifiter:transactionManagerreadOnlay:false

SimpleMetadataReader
构造方法传递三个参数直接使用
```java final class SimpleMetadataReader implements MetadataReader {
private static final int PARSING_OPTIONS = ClassReader.SKIP_DEBUG
| ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES;
private final Resource resource;
private final AnnotationMetadata annotationMetadata;
SimpleMetadataReader(Resource resource, @Nullable ClassLoader classLoader) throws IOException {SimpleAnnotationMetadataReadingVisitor visitor = new SimpleAnnotationMetadataReadingVisitor(classLoader);getClassReader(resource).accept(visitor, PARSING_OPTIONS);this.resource = resource;this.annotationMetadata = visitor.getMetadata();}private static ClassReader getClassReader(Resource resource) throws IOException {try (InputStream is = new BufferedInputStream(resource.getInputStream())) {try {return new ClassReader(is);}catch (IllegalArgumentException ex) {throw new NestedIOException("ASM ClassReader failed to parse class file - " +"probably due to a new Java class file version that isn't supported yet: " + resource, ex);}}}@Overridepublic Resource getResource() {return this.resource;}@Overridepublic ClassMetadata getClassMetadata() {return this.annotationMetadata;}@Overridepublic AnnotationMetadata getAnnotationMetadata() {return this.annotationMetadata;}
}
## SimpleMetadataReaderFactory- 关注点为如何获取`MetadataReader`1. 通过资源直接 new 出来2. 通过 className 转换成资源地址,3. 将资源地址转换成`Resource`对象4. new 出来```java@Overridepublic MetadataReader getMetadataReader(String className) throws IOException {try {String resourcePath = ResourceLoader.CLASSPATH_URL_PREFIX +ClassUtils.convertClassNameToResourcePath(className) + ClassUtils.CLASS_FILE_SUFFIX;Resource resource = this.resourceLoader.getResource(resourcePath);return getMetadataReader(resource);}catch (FileNotFoundException ex) {// Maybe an inner class name using the dot name syntax? Need to use the dollar syntax here...// ClassUtils.forName has an equivalent check for resolution into Class references later on.int lastDotIndex = className.lastIndexOf('.');if (lastDotIndex != -1) {String innerClassName =className.substring(0, lastDotIndex) + '$' + className.substring(lastDotIndex + 1);String innerClassResourcePath = ResourceLoader.CLASSPATH_URL_PREFIX +ClassUtils.convertClassNameToResourcePath(innerClassName) + ClassUtils.CLASS_FILE_SUFFIX;Resource innerClassResource = this.resourceLoader.getResource(innerClassResourcePath);if (innerClassResource.exists()) {return getMetadataReader(innerClassResource);}}throw ex;}}@Overridepublic MetadataReader getMetadataReader(Resource resource) throws IOException {return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader());}
