Spring相关源码解析
创始人
2024-03-26 19:20:35
0

目录

Spring元数据

Spring Conditional

Spring MultiValueMap

Spring MethodOverride


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 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#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> {//确定注解是否存在 boolean isPresent(Class annotationType);//注解是否直接存在 boolean isDirectlyPresent(Class annotationType);// 获取匹配的注解 MergedAnnotation get(Class annotationType);// 省略其他}
  • 这个接口中还有两个方法

    1. of 将多个MergedAnnotations合并

    2. 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
}
@Override
public  MergedAnnotation get(String annotationType,@Nullable Predicate> 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, java.util.function.BiPredicate>)

@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,T>, org.springframework.core.annotation.MergedAnnotation.Adapt...)

@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
    1. 通过资源直接 new 出来
    2. 通过 className 转换成资源地址,
    3. 将资源地址转换成Resource对象
    4. new 出来
@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());
}

Spring Conditional

Conditional

@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {/*** 多个匹配器接口*/Class[] value();}

Condition

@FunctionalInterface
public interface Condition {/*** 匹配,如果匹配返回true进行初始化,返回false跳过初始化*/boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);}
  • ConditionContext 上下文
  • AnnotatedTypeMetadata 注解信息

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#doRegisterBean

shouldSkip

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[] qualifiers, @Nullable Supplier supplier,@Nullable BeanDefinitionCustomizer[] customizers) {AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);// 和条件注解相关的函数if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}// 省略其他
}

Spring MultiValueMap

  • 类路径: 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 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 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;}
}

Spring MethodOverride

  • MethodOverride 方法重载类

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)

    1. lookup-method 标签

    2. replaced-method 标签

LookupOverride

  • org.springframework.beans.factory.support.LookupOverride
  • lookup-method 标签对应的实体对象
@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.createBeanDefinition
public 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;
}

相关内容

热门资讯

每周股票复盘:四方光电(688... 截至2025年12月26日收盘,四方光电(688665)报收于49.67元,较上周的47.84元上涨...
黑龙江哈尔滨建立住宅物业管理联... 为全面提升住宅小区精细化管理水平,黑龙江省哈尔滨市印发《哈尔滨市住宅物业管理联席会议制度》,通过构建...
长沙市自动驾驶汽车发展条例 长沙市人民代表大会常务委员会公告 (2025年第16号) 《长沙市自动驾驶汽车发展条例》已经2025...
一次性信用修复政策哪些情况能享... 12月22日,中国人民银行发布《关于实施一次性信用修复政策有关安排的通知》,明确央行征信系统(金融信...
苹果与麦斯莫专利纠纷:法官驳回... 【苹果与麦斯莫血氧监测专利纠纷有新进展,苹果可继续美售更新款智能手表】12月27日消息,美国苹果公司...
河南省举行《河南省优化营商环境... 原标题: 我省举行《河南省优化营商环境条例》新闻发布会 以法治护航民营经济高质量发展(新闻发布厅) ...
六“字”解码《河南省优化营商环... 市场壁垒如何破除? 关键堵点怎样打通? 企业权益如何保障? 中小企业怎样融资? 如何做到无事不扰? ...
中国经济“四稳”政策:激活内生... 【12月28日消息,“四稳”政策助力稳增长】自2025年4月25日中央政治局会议首提“着力稳就业、稳...
这里既有产业基础又有政策支持 应聘者正在有序入场。 招聘单位和应聘者进行供需对接。 香港理工大学珠三角校友会为校友提供信息咨询...
关于《长沙市自动驾驶汽车发展条... 记者:请问《条例》的颁布,对于长沙自动驾驶汽车产业发展将有何助力作用? 市工业和信息化局党组成员、副...