目录
Spring元数据
Spring Conditional
Spring MultiValueMap
Spring MethodOverride
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 getAnnotationAttributes(String annotationName) {return getAnnotationAttributes(annotationName, false);}// 省略其他}
AnnotationMetadata
public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata {/*** 获取注解名称,全类名*/default Set getAnnotationTypes() {return getAnnotations().stream().filter(MergedAnnotation::isDirectlyPresent).map(annotation -> annotation.getType().getName()).collect(Collectors.toCollection(LinkedHashSet::new));}/*** 注解全类名*/default Set 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 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 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 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 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
@Nullable
public Map 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@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#getMergedAnnotationAttributesOnClassWithLocalAnnotationgetAnnotations
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);
}
MergedAnnotations
public interface MergedAnnotations extends Iterable> {//确定注解是否存在 boolean isPresent(Class annotationType);//注解是否直接存在 boolean isDirectlyPresent(Class annotationType);// 获取匹配的注解 MergedAnnotation get(Class 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* and 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>, org.springframework.core.annotation.MergedAnnotationSelector)@Override
public MergedAnnotation get(String annotationType,@Nullable Predicate super MergedAnnotation> predicate,@Nullable MergedAnnotationSelector selector) {// 匹配校验if (this.annotationFilter.matches(annotationType)) {return MergedAnnotation.missing();}MergedAnnotation 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
@Nullable
static R scan(C context, AnnotatedElement source, SearchStrategy searchStrategy,AnnotationsProcessor processor, @Nullable BiPredicate> classFilter) {R result = process(context, source, searchStrategy, processor, classFilter);return processor.finish(result);
}
PROCESS方法
@Nullable
private static R process(C context, AnnotatedElement source,SearchStrategy searchStrategy, AnnotationsProcessor processor,@Nullable BiPredicate> 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 {}
@Nullable
private static R processClass(C context, Class> source,SearchStrategy searchStrategy, AnnotationsProcessor processor,@Nullable BiPredicate> 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);
}
最后的组装 map 方法
org.springframework.core.annotation.TypeMappedAnnotation#asMap(java.util.function.Function
@Override
public AnnotationAttributes asAnnotationAttributes(Adapt... adaptations) {return asMap(mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType()), adaptations);
}
@Override
public > T asMap(Function, 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;
}
SimpleMetadataReader
构造方法传递三个参数直接使用
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 Resource对象@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());
}
Conditional
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {/*** 多个匹配器接口*/Class extends Condition>[] value();}
Condition
@FunctionalInterface
public interface Condition {/*** 匹配,如果匹配返回true进行初始化,返回false跳过初始化*/boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);}
ConditionContext
public interface ConditionContext {/*** bean的定义*/BeanDefinitionRegistry getRegistry();/*** bean 工厂*/@NullableConfigurableListableBeanFactory getBeanFactory();/*** 环境*/Environment getEnvironment();/*** 资源加载器*/ResourceLoader getResourceLoader();/*** 类加载器*/@NullableClassLoader getClassLoader();}
唯一实现 : org.springframework.context.annotation.ConditionEvaluator.ConditionContextImpl
构造方法
public ConditionContextImpl(@Nullable BeanDefinitionRegistry registry,@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {this.registry = registry;this.beanFactory = deduceBeanFactory(registry);this.environment = (environment != null ? environment : deduceEnvironment(registry));this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));this.classLoader = deduceClassLoader(resourceLoader, this.beanFactory);
}
AnnotatedTypeMetadata
public interface AnnotatedTypeMetadata {/*** 获取所有注解*/MergedAnnotations getAnnotations();/*** 是否有注解*/default boolean isAnnotated(String annotationName) {return getAnnotations().isPresent(annotationName);}/*** 获取注解的属性*/@Nullabledefault Map getAnnotationAttributes(String annotationName) {return getAnnotationAttributes(annotationName, false);}}
org.springframework.context.annotation.ConfigurationClassWithConditionTests@Test
public void conditionalOnMissingBeanMatch() throws Exception {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();ctx.register(BeanOneConfiguration.class, BeanTwoConfiguration.class);ctx.refresh();assertThat(ctx.containsBean("bean1")).isTrue();assertThat(ctx.containsBean("bean2")).isFalse();assertThat(ctx.containsBean("configurationClassWithConditionTests.BeanTwoConfiguration")).isFalse();
}@Configurationstatic class BeanOneConfiguration {@Beanpublic ExampleBean bean1() {return new ExampleBean();}}@Configuration@Conditional(NoBeanOneCondition.class)static class BeanTwoConfiguration {@Beanpublic ExampleBean bean2() {return new ExampleBean();}}static class NoBeanOneCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return !context.getBeanFactory().containsBeanDefinition("bean1");}}
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBeanshouldSkip
public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {return false;}if (phase == null) {if (metadata instanceof AnnotationMetadata &&ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);}return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);}List conditions = new ArrayList<>();// 获取注解 Conditional 的属性值for (String[] conditionClasses : getConditionClasses(metadata)) {for (String conditionClass : conditionClasses) {// 序列化成注解Condition condition = getCondition(conditionClass, this.context.getClassLoader());// 插入注解列表conditions.add(condition);}}AnnotationAwareOrderComparator.sort(conditions);for (Condition condition : conditions) {ConfigurationPhase requiredPhase = null;if (condition instanceof ConfigurationCondition) {requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();}// matches 进行验证if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this.context, metadata)) {return true;}}return false;
}
读取注解信息, 并且执行注解对应的类的方法。 实例化BeanTwoConfiguration对象的时候会去执行NoBeanOneCondition方法
@Configuration
@Conditional(NoBeanOneCondition.class)
static class BeanTwoConfiguration {@Beanpublic ExampleBean bean2() {return new ExampleBean();}
}static class NoBeanOneCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return !context.getBeanFactory().containsBeanDefinition("bean1");}}
在开发中可以自定义 matches 规则
private void doRegisterBean(Class beanClass, @Nullable String name,@Nullable Class extends Annotation>[] qualifiers, @Nullable Supplier supplier,@Nullable BeanDefinitionCustomizer[] customizers) {AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);// 和条件注解相关的函数if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}// 省略其他
}
类路径: org.springframework.util.MultiValueMap
public interface MultiValueMap extends Map> {/*** 获取value的第一*/@NullableV getFirst(K key);/*** 添加元素*/void add(K key, @Nullable V value);/*** 添加所有元素*/void addAll(K key, List extends V> values);/*** 添加要给 {@link MultiValueMap} 对象*/void addAll(MultiValueMap values);default void addIfAbsent(K key, @Nullable V value) {if (!containsKey(key)) {add(key, value);}}/*** 设置数据*/void set(K key, @Nullable V value);/*** 设置一个map数据*/void setAll(Map values);/*** 转换成 map 结构*/Map toSingleValueMap();}
LinkedMultiValueMap
public class LinkedMultiValueMap implements MultiValueMap, Serializable, Cloneable {@Override@Nullablepublic V getFirst(K key) {// 获取listList values = this.targetMap.get(key);// 获取 list 的第一个return (values != null && !values.isEmpty() ? values.get(0) : null);}@Overridepublic void add(K key, @Nullable V value) {// 从当前内存中获取key对应的list.List values = this.targetMap.computeIfAbsent(key, k -> new LinkedList<>());// 将value 插入到values中values.add(value);}@Overridepublic void addAll(K key, List extends V> values) {// 从当前内存中获取key对应的list.List currentValues = this.targetMap.computeIfAbsent(key, k -> new LinkedList<>());// 将value 插入到values中currentValues.addAll(values);}@Overridepublic void addAll(MultiValueMap values) {for (Entry> entry : values.entrySet()) {addAll(entry.getKey(), entry.getValue());}}@Overridepublic void set(K key, @Nullable V value) {// 构造listList values = new LinkedList<>();// 添加values.add(value);// 添加this.targetMap.put(key, values);}@Overridepublic void setAll(Map values) {// 循环执行 set 方法values.forEach(this::set);}@Overridepublic Map toSingleValueMap() {// 返回结果定义LinkedHashMap singleValueMap = new LinkedHashMap<>(this.targetMap.size());// 循环this.targetMap.forEach((key, values) -> {if (values != null && !values.isEmpty()) {// value 获取原来list中的第一个元素singleValueMap.put(key, values.get(0));}});return singleValueMap;}
}
在MethodOverride定义了三个属性:方法名称、是否重载、源
public abstract class MethodOverride implements BeanMetadataElement {/*** 方法名称*/private final String methodName;/*** 是否重载*/private boolean overloaded = true;/*** 源*/@Nullableprivate Object source;
}
public abstract boolean matches(Method method);
在 Spring 中有两种可以重写的机制(XML)
lookup-method 标签
replaced-method 标签
LookupOverride
org.springframework.beans.factory.support.LookupOverride@Nullable
private final String beanName;@Nullable
private Method method;
matches 比较方法
@Overridepublic boolean matches(Method method) {if (this.method != null) {// 通过 equals 判断return method.equals(this.method);}else {// 1. method 名称是否相同// 2. 是否需要重载// 3. 是不是 ABSTRACT 方法// 4. 参数列表长度是否等于0return (method.getName().equals(getMethodName()) && (!isOverloaded() ||Modifier.isAbstract(method.getModifiers()) || method.getParameterCount() == 0));}}
ReplaceOverride
org.springframework.beans.factory.support.ReplaceOverride/*** 实现 MethodReplacer 接口的bean name* @see MethodReplacer*/
private final String methodReplacerBeanName;/*** 标签 arg-type 数据*/
private final List typeIdentifiers = new LinkedList<>();
例子
String
methodReplacerBeanName 对应org.springframework.beans.factory.support.MethodReplacer 的实现类
typeIdentifiers 对应标签 arg-type 的属性值
构造方法
public ReplaceOverride(String methodName, String methodReplacerBeanName) {super(methodName);Assert.notNull(methodName, "Method replacer bean name must not be null");this.methodReplacerBeanName = methodReplacerBeanName;
}
methodName 通过父类进行设置
matches
@Override
public boolean matches(Method method) {// 方法名称是否相同if (!method.getName().equals(getMethodName())) {return false;}// 是否重载if (!isOverloaded()) {// Not overloaded: don't worry about arg type matching...return true;}// If we get here, we need to insist on precise argument matching...// 类型标识数量是否和参数列表是否不相同if (this.typeIdentifiers.size() != method.getParameterCount()) {return false;}// 获取参数类型列表Class>[] parameterTypes = method.getParameterTypes();for (int i = 0; i < this.typeIdentifiers.size(); i++) {String identifier = this.typeIdentifiers.get(i);// 判断 方法参数的类型是否在类型标识列表中if (!parameterTypes[i].getName().contains(identifier)) {return false;}}return true;
}
MethodOverrides
org.springframework.beans.factory.support.MethodOverrides
重载方法对象
存储所有重载的方法列表(set 结构)
private final Set overrides = new CopyOnWriteArraySet<>();
添加 MethodOverride
public void addOverride(MethodOverride override) {this.overrides.add(override);
}public void addOverrides(@Nullable MethodOverrides other) {if (other != null) {this.overrides.addAll(other.overrides);}
}
获取 MethodOverride
@Nullable
public MethodOverride getOverride(Method method) {MethodOverride match = null;for (MethodOverride candidate : this.overrides) {if (candidate.matches(method)) {match = candidate;}}return match;
}
Spring BeanDefinitionReaderUtils
createBeanDefinition
org.springframework.beans.factory.support.BeanDefinitionReaderUtils.createBeanDefinitionpublic static AbstractBeanDefinition createBeanDefinition(@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {GenericBeanDefinition bd = new GenericBeanDefinition();// 设置 父beanbd.setParentName(parentName);if (className != null) {if (classLoader != null) {// 设置 class// 内部是通过反射创建 classbd.setBeanClass(ClassUtils.forName(className, classLoader));}else {// 设置 class namebd.setBeanClassName(className);}}return bd;
}
generateBeanName
org.springframework.beans.factory.support.BeanDefinitionReaderUtils.generateBeanName(org.springframework.beans.factory.config.BeanDefinition, org.springframework.beans.factory.support.BeanDefinitionRegistry, boolean)public static String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean)throws BeanDefinitionStoreException {// 获取 bean class 的名称// Class.getName()String generatedBeanName = definition.getBeanClassName();if (generatedBeanName == null) {// 父类名称是否存在if (definition.getParentName() != null) {generatedBeanName = definition.getParentName() + "$child";}// 工厂 beanName 是否为空else if (definition.getFactoryBeanName() != null) {generatedBeanName = definition.getFactoryBeanName() + "$created";}}if (!StringUtils.hasText(generatedBeanName)) {throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither " +"'class' nor 'parent' nor 'factory-bean' - can't generate bean name");}String id = generatedBeanName;if (isInnerBean) {// Inner bean: generate identity hashcode suffix.// 组装名称// 生成名称 + # + 16 进制的一个字符串id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(definition);}else {// Top-level bean: use plain class name with unique suffix if necessary.// 唯一beanName设置// // beanName + # + 序号return uniqueBeanName(generatedBeanName, registry);}return id;}
uniqueBeanName
public static String uniqueBeanName(String beanName, BeanDefinitionRegistry registry) {String id = beanName;int counter = -1;// Increase counter until the id is unique.while (counter == -1 || registry.containsBeanDefinition(id)) {counter++;// beanName + # + 序号id = beanName + GENERATED_BEAN_NAME_SEPARATOR + counter;}return id;
}
registerBeanDefinition
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)throws BeanDefinitionStoreException {// Register bean definition under primary name.// 获取 beanNameString beanName = definitionHolder.getBeanName();// 注册bean definitionregistry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());// Register aliases for bean name, if any.// 别名列表String[] aliases = definitionHolder.getAliases();// 注册别名列表if (aliases != null) {for (String alias : aliases) {registry.registerAlias(beanName, alias);}}
}
registerWithGeneratedName
public static String registerWithGeneratedName(AbstractBeanDefinition definition, BeanDefinitionRegistry registry)throws BeanDefinitionStoreException {// 生成一个 beanNameString generatedName = generateBeanName(definition, registry, false);// 注册 bean Definitionregistry.registerBeanDefinition(generatedName, definition);return generatedName;
}