doc:spring元数据
This commit is contained in:
parent
c6f643319f
commit
ad20a9071e
997
docs/Spring/clazz/Spring-Metadata.md
Normal file
997
docs/Spring/clazz/Spring-Metadata.md
Normal file
@ -0,0 +1,997 @@
|
||||
# Spring 元信息
|
||||
|
||||
- Author: [HuiFer](https://github.com/huifer)
|
||||
- 源码阅读仓库: [SourceHot-Spring](https://github.com/SourceHot/spring-framework-read)
|
||||
|
||||
|
||||
## ClassMetadata
|
||||
|
||||
|
||||
|
||||
|
||||
```java
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是基础类
|
||||
*/
|
||||
@Nullable
|
||||
String getEnclosingClassName();
|
||||
|
||||
/**
|
||||
* 是否有父类
|
||||
*/
|
||||
default boolean hasSuperClass() {
|
||||
return (getSuperClassName() != null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 父类名称
|
||||
*/
|
||||
@Nullable
|
||||
String getSuperClassName();
|
||||
|
||||
/**
|
||||
* 实现类名称列表
|
||||
*/
|
||||
String[] getInterfaceNames();
|
||||
|
||||
/**
|
||||
* 成员列表
|
||||
* @since 3.1
|
||||
*/
|
||||
String[] getMemberClassNames();
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## AnnotatedTypeMetadata
|
||||
|
||||
|
||||
|
||||
```java
|
||||
public interface AnnotatedTypeMetadata {
|
||||
|
||||
/**
|
||||
* 获取所有注解
|
||||
*/
|
||||
MergedAnnotations getAnnotations();
|
||||
|
||||
/**
|
||||
* 是否有注解
|
||||
*/
|
||||
default boolean isAnnotated(String annotationName) {
|
||||
return getAnnotations().isPresent(annotationName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取注解的属性
|
||||
*/
|
||||
@Nullable
|
||||
default Map<String, Object> getAnnotationAttributes(String annotationName) {
|
||||
return getAnnotationAttributes(annotationName, false);
|
||||
}
|
||||
// 省略其他
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
##
|
||||
|
||||
## AnnotationMetadata
|
||||
|
||||
```java
|
||||
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
|
||||
|
||||
```java
|
||||
public interface MethodMetadata extends AnnotatedTypeMetadata {
|
||||
|
||||
/**
|
||||
* 方法名称
|
||||
*/
|
||||
String getMethodName();
|
||||
|
||||
/**
|
||||
* 方法全路径
|
||||
*/
|
||||
String getDeclaringClassName();
|
||||
|
||||
/**
|
||||
* 返回值类型
|
||||
*/
|
||||
String getReturnTypeName();
|
||||
|
||||
/**
|
||||
* 是不是abstrac修饰
|
||||
*/
|
||||
boolean isAbstract();
|
||||
|
||||
/**
|
||||
* 是否 static 修饰
|
||||
*/
|
||||
boolean isStatic();
|
||||
|
||||
/**
|
||||
* 是否 final 修饰
|
||||
*/
|
||||
boolean isFinal();
|
||||
|
||||
/**
|
||||
* 是否重载
|
||||
*/
|
||||
boolean isOverridable();
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## MetadataReader
|
||||
|
||||
```java
|
||||
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
|
||||
|
||||
```java
|
||||
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对象. 之后使用这个对象的方法
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```java
|
||||
public class StandardClassMetadata implements ClassMetadata {
|
||||
|
||||
private final Class<?> introspectedClass;
|
||||
|
||||
@Deprecated
|
||||
public 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;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getClassName() {
|
||||
return this.introspectedClass.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInterface() {
|
||||
return this.introspectedClass.isInterface();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAnnotation() {
|
||||
return this.introspectedClass.isAnnotation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return Modifier.isAbstract(this.introspectedClass.getModifiers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return Modifier.isFinal(this.introspectedClass.getModifiers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isIndependent() {
|
||||
return (!hasEnclosingClass() ||
|
||||
(this.introspectedClass.getDeclaringClass() != null &&
|
||||
Modifier.isStatic(this.introspectedClass.getModifiers())));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getEnclosingClassName() {
|
||||
Class<?> enclosingClass = this.introspectedClass.getEnclosingClass();
|
||||
return (enclosingClass != null ? enclosingClass.getName() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getSuperClassName() {
|
||||
Class<?> superClass = this.introspectedClass.getSuperclass();
|
||||
return (superClass != null ? superClass.getName() : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public 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
|
||||
- 如果这个方法有注解,会进行注解的解析
|
||||
|
||||
|
||||
|
||||
```java
|
||||
public class StandardMethodMetadata implements MethodMetadata {
|
||||
|
||||
private final Method introspectedMethod;
|
||||
|
||||
private final boolean nestedAnnotationsAsMap;
|
||||
|
||||
private final MergedAnnotations mergedAnnotations;
|
||||
|
||||
@Deprecated
|
||||
public StandardMethodMetadata(Method introspectedMethod) {
|
||||
this(introspectedMethod, false);
|
||||
}
|
||||
|
||||
|
||||
@Deprecated
|
||||
public 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());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public MergedAnnotations getAnnotations() {
|
||||
return this.mergedAnnotations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying Method.
|
||||
*/
|
||||
public final Method getIntrospectedMethod() {
|
||||
return this.introspectedMethod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodName() {
|
||||
return this.introspectedMethod.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeclaringClassName() {
|
||||
return this.introspectedMethod.getDeclaringClass().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReturnTypeName() {
|
||||
return this.introspectedMethod.getReturnType().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAbstract() {
|
||||
return Modifier.isAbstract(this.introspectedMethod.getModifiers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return Modifier.isStatic(this.introspectedMethod.getModifiers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinal() {
|
||||
return Modifier.isFinal(this.introspectedMethod.getModifiers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverridable() {
|
||||
return !isStatic() && !isFinal() && !isPrivate();
|
||||
}
|
||||
|
||||
private boolean isPrivate() {
|
||||
return Modifier.isPrivate(this.introspectedMethod.getModifiers());
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public 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
|
||||
@Nullable
|
||||
public 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
|
||||
|
||||
```java
|
||||
@Override
|
||||
@Nullable
|
||||
public 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#getAnnotationAttributes`
|
||||
- `org.springframework.core.annotation.MergedAnnotation#asAnnotationAttributes`
|
||||
|
||||
|
||||
|
||||
```java
|
||||
@Nullable
|
||||
public 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)`
|
||||
|
||||
|
||||
|
||||
- 最终我们找到的代码如下
|
||||
|
||||
```java
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```java
|
||||
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);
|
||||
// 省略其他
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
- 这个接口中还有两个方法
|
||||
|
||||
1. `of`
|
||||
将多个`MergedAnnotations`合并
|
||||
|
||||
2. `from`
|
||||
|
||||
将多个注解合并
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### SearchStrategy
|
||||
|
||||
```java
|
||||
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>)`
|
||||
|
||||
```java
|
||||
@Override
|
||||
public <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<?>>)`
|
||||
|
||||
```java
|
||||
@Nullable
|
||||
static <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`方法
|
||||
|
||||
```java
|
||||
@Nullable
|
||||
private 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);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
测试类
|
||||
|
||||
```java
|
||||
@Transactional("TxConfig")
|
||||
static class TxConfig {
|
||||
}
|
||||
```
|
||||
|
||||
显然这是一个类他会走`processClass`方法
|
||||
|
||||
|
||||
|
||||
- 根据扫描方式进行扫描
|
||||
|
||||
```java
|
||||
@Nullable
|
||||
private 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...)`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
```java
|
||||
@Override
|
||||
public AnnotationAttributes asAnnotationAttributes(Adapt... adaptations) {
|
||||
return asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType()), adaptations);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
```java
|
||||
@Override
|
||||
public <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: 函数对应的值
|
||||
|
||||
|
||||
|
||||
```java
|
||||
@Transactional("TxConfig")
|
||||
```
|
||||
|
||||
```java
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE, ElementType.METHOD})
|
||||
@Inherited
|
||||
@interface Transactional {
|
||||
|
||||
String value() default "";
|
||||
|
||||
String qualifier() default "transactionManager";
|
||||
|
||||
boolean readOnly() default false;
|
||||
}
|
||||
```
|
||||
|
||||
如果是上面这样的结构那么返回值为
|
||||
|
||||
```json
|
||||
value:TxConfig
|
||||
qulifiter:transactionManager
|
||||
readOnlay: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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Resource getResource() {
|
||||
return this.resource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassMetadata getClassMetadata() {
|
||||
return this.annotationMetadata;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationMetadata getAnnotationMetadata() {
|
||||
return this.annotationMetadata;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## SimpleMetadataReaderFactory
|
||||
|
||||
- 关注点为如何获取`MetadataReader`
|
||||
1. 通过资源直接new出来
|
||||
2. 通过className转换成资源地址,
|
||||
3. 将资源地址转换成`Resource`对象
|
||||
4. new出来
|
||||
|
||||
```java
|
||||
@Override
|
||||
public 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;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public MetadataReader getMetadataReader(Resource resource) throws IOException {
|
||||
return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader());
|
||||
}
|
||||
```
|
BIN
images/spring/image-20200824094154847.png
Normal file
BIN
images/spring/image-20200824094154847.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
BIN
images/spring/image-20200824104529315.png
Normal file
BIN
images/spring/image-20200824104529315.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Loading…
x
Reference in New Issue
Block a user