Spring启动之bean定义注册

1、前言

  • Spring容器在本文可以简单理解为DefaultListableBeanFactory,它是BeanFactory的实现类,这个类有几个非常重要的属性:beanDefinitionMap是一个map,用来存放bean所对应的BeanDefinition;beanDefinitionNames是一个List集合,用来存放所有bean的name;singletonObjects是一个Map,用来存放所有创建好的单例Bean

2、入口

2.1、主方法

public static void main(String[] args) {
    AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(ComponentScanTest.class);
    String[] beanDefinitionNames = acac.getBeanDefinitionNames();
    Arrays.asList(beanDefinitionNames).stream().forEach(System.out::println);
}

2.2、配置类

  • ComponentScanTest 类是一个配置类,类上加了两个注解,加 @Configuration 表明``ComponentScanTest是一个配置类,加@ComponentScan是为了告诉Spring` 要扫描哪些包
// 不加该注解也可扫描到
@Configuration
@ComponentScan("org.springframework.test")
public class ComponentScanTest {
}

3、AnnotationConfigApplicationContext构造方法

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
	this();
    // 注册bean定义
	register(annotatedClasses);
	refresh();
}

4、register方法调用

// annotatedClasses可传入多个配置类
public void register(Class<?>... annotatedClasses) {
    Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
    // reader为this方法中初始化的AnnotatedBeanDefinitionReader
    this.reader.register(annotatedClasses);
}

// 循环注册传入每一个配置类
public void register(Class<?>... annotatedClasses) {
    for (Class<?> annotatedClass : annotatedClasses) {
        registerBean(annotatedClass);
    }
}

public void registerBean(Class<?> annotatedClass) {
    // 注册逻辑实现
    doRegisterBean(annotatedClass, null, null, null);
}

5、doRegisterBean注册BeanDefinition

// 遍历annotatedClass数组进行注册
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
                        @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

    // 1.初始化一个通用的注解Bean定义(包含类的信息、类上的所有注解信息)
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
    // 2.解析@Conditional注解,是否跳过该bean定义的注册。调用AnnotationConfigApplicationContext的this()方法时初始化过conditionEvaluator(包含beanFactory,bean)
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
        return;
    }

    // 3.用于创建bean实例的回调,instanceSupplier默认值为null
    abd.setInstanceSupplier(instanceSupplier);
    // 4.解析@Scope注解,没配置则bean默认是单例、不创建动态代理(有配置没配置名称时,名称为空串。无配置时,名称为singleton)
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
    // 5.bean名称生成器beanNameGenerator,默认为:AnnotationBeanNameGenerator,生成名称默认为类名首字母小写
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

    // 6.处理@Lazy、@Primary、@DependsOn、@Role、@Description通用注解,将属性值设置到abd中
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    if (qualifiers != null) {
        for (Class<? extends Annotation> qualifier : qualifiers) {
            if (Primary.class == qualifier) {
                abd.setPrimary(true);
            } else if (Lazy.class == qualifier) {
                abd.setLazyInit(true);
            } else {
                abd.addQualifier(new AutowireCandidateQualifier(qualifier));
            }
        }
    }
    for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
        customizer.customize(abd);
    }

    // 将bean定义和bean名称封装(返回AnnotatedGenericBeanDefinition)
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    // 7. @scope如果配置的代理类(返回RootBeanDefinition),则注册原bean定义
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    // 8.如果有代理类,注册代理bean定义,没有则注册原bean定义
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

5.1 初始化AnnotatedGenericBeanDefinition

在这里插入图片描述

// beanClass为配置类
public AnnotatedGenericBeanDefinition(Class<?> beanClass) {
    // 给父类AbstractBeanDefinition属性beanClass赋值
    setBeanClass(beanClass);
    // AnnotationMetadata默认初始化为StandardAnnotationMetadata,存储类信息,及类上标注的注解
    // nestedAnnotationsAsMap嵌套注解是否转map入参默认值为 = true
    this.metadata = new StandardAnnotationMetadata(beanClass, true);
}

5.2、解析@Conditional注解,判断是否跳过注册

// metadata为5.1中初始化的StandardAnnotationMetadata,phase = null
public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {
    // 1. 元数据为空,或元数据包含的所有注解中不存在@Conditional注解
    if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
        return false;
    }
	
   // 此处为初始化容器阶段,一般不会配置@Conditional注解,省略其他代码。。。。。。
}
5.2.1、isAnnotated校验类是否标注指定注解
// annotationName指定的注解类名称
public boolean isAnnotated(String annotationName) {
    // this = StandardAnnotationMetadata
    // 1.判断配置类上是否存在注解;2.Spring实现的解析注解工具类中实现查找检验方法
    return (this.annotations.length > 0 &&
            AnnotatedElementUtils.isAnnotated(getIntrospectedClass(), annotationName));
}
5.2.2、解析注解,判断是否存在指定注解
// element为jdk内置类:java.lang.reflect.AnnotatedElement,可接受一个Class实参
public static boolean isAnnotated(AnnotatedElement element, String annotationName) {
    // equals方法只有返回true才为真
    return Boolean.TRUE.equals(searchWithGetSemantics(element, null, annotationName, alwaysTrueAnnotationProcessor));
}
5.2.3、searchWithGetSemantics
  • org.springframework.core.annotation.AnnotatedElementUtils

  • 通过递归当前类及其从父类继承的注解,查找符合对应名称的注解后,获取其属性值

private static <T> T searchWithGetSemantics(AnnotatedElement element,
                                            @Nullable Class<? extends Annotation> annotationType, @Nullable String annotationName,
                                            @Nullable Class<? extends Annotation> containerType, Processor<T> processor,
                                            Set<AnnotatedElement> visited, int metaDepth) {

    // set的add方法在添加重复对象时返回false
    if (visited.add(element)) {
        try {
            // Start searching within locally declared annotations
            // 1.开始在当前类型element上标注的注释中搜索和annotationName相同的注释
            List<Annotation> declaredAnnotations = Arrays.asList(element.getDeclaredAnnotations());
            T result = searchWithGetSemanticsInAnnotations(element, declaredAnnotations,
                                                           annotationType, annotationName, containerType, processor, visited, metaDepth);
            if (result != null) {
                return result;
            }

            // 2. 若1中result值为null,则会在element从父类继承来的注解中查找
            if (element instanceof Class) {  // otherwise getAnnotations doesn't return anything new
                Class<?> superclass = ((Class) element).getSuperclass();
                if (superclass != null && superclass != Object.class) {
                    // 存放通过类继承的注解(标注了@Inherited元注解的注解)
                    List<Annotation> inheritedAnnotations = new LinkedList<>();
                    for (Annotation annotation : element.getAnnotations()) {
                        // 子类的注解中不包含父类的注解
                        if (!declaredAnnotations.contains(annotation)) {
                            inheritedAnnotations.add(annotation);
                        }
                    }
                    // Continue searching within inherited annotations
                    // 继续在element继承的注释中搜索
                    result = searchWithGetSemanticsInAnnotations(element, inheritedAnnotations,
                                                                 annotationType, annotationName, containerType, processor, visited, metaDepth);
                    if (result != null) {
                        return result;
                    }
                }
            }
        }
        catch (Throwable ex) {
            AnnotationUtils.handleIntrospectionFailure(element, ex);
        }
    }

    return null;
}
5.2.4、searchWithGetSemanticsInAnnotations
  • org.springframework.core.annotation.AnnotatedElementUtils

  • 遍历注解,解析对应注解的属性值

private static <T> T searchWithGetSemanticsInAnnotations(@Nullable AnnotatedElement element,
                                                         List<Annotation> annotations, @Nullable Class<? extends Annotation> annotationType,
                                                         @Nullable String annotationName, @Nullable Class<? extends Annotation> containerType,
                                                         Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth) {

    // Search in annotations
    // 1.遍历所有当前注解,在列表中查找
    for (Annotation annotation : annotations) {
        // 获取注解类型class
        Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
        // 当前注解是否为java.lang.annotation开头的注解,是 true
        if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
            if (currentAnnotationType == annotationType ||
                currentAnnotationType.getName().equals(annotationName) ||
                // 始终处理暂时不知道什么用,默认值为false
                processor.alwaysProcesses()) {
                T result = processor.process(element, annotation, metaDepth);
                if (result != null) {
                    // register方法解析@Scope注解时初始化MergedAnnotationAttributesProcessor,aggregates默认为false
                    if (processor.aggregates() && metaDepth == 0) {
                        processor.getAggregatedResults().add(result);
                    }
                    else {
                        return result;
                    }
                }
            }
            // Repeatable annotations in container?
            // 是否为可重复的(注解中有属性是个注解数组,如:@ComponentScans))
            else if (currentAnnotationType == containerType) {
                for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) {
                    T result = processor.process(element, contained, metaDepth);
                    if (result != null) {
                        // No need to post-process since repeatable annotations within a
                        // container cannot be composed annotations.
                        processor.getAggregatedResults().add(result);
                    }
                }
            }
        }
    }

    // Recursively search in meta-annotations
    // 2、遍历当前的注解,递归去当前注解上标注的注解中查找
    for (Annotation annotation : annotations) {
        Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
        // 确定当前注解不是jdk的元注解,是返回false
        if (hasSearchableMetaAnnotations(currentAnnotationType, annotationType, annotationName)) {
            // 循环element类上的每一个非java或Nullable注解
            T result = searchWithGetSemantics(currentAnnotationType, annotationType,
                                              annotationName, containerType, processor, visited, metaDepth + 1);
            if (result != null) {
                processor.postProcess(element, annotation, result);
                if (processor.aggregates() && metaDepth == 0) {
                    processor.getAggregatedResults().add(result);
                }
                else {
                    return result;
                }
            }
        }
    }

    return null;
}
5.2.5、@Confitional的process实现
  • org.springframework.core.annotation.AnnotatedElementUtils
static class AlwaysTrueBooleanAnnotationProcessor extends SimpleAnnotationProcessor<Boolean> {

   @Override
   public final Boolean process(@Nullable AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) {
       // 始终返回true
      return Boolean.TRUE;
   }
}

5.3、解析@Scope注解

public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
    // 初始化时默认为scopeName = singleton,ScopedProxyMode = no
    ScopeMetadata metadata = new ScopeMetadata();
    if (definition instanceof AnnotatedBeanDefinition) {
        AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
        // 将@Scope解析为AnnotationAttributes(LinkedHashMap),scopeAnnotationType = Scope.class,如果未标注该注解,则返回null,该方法的调用过程和5.2的解析相同
        AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
            annDef.getMetadata(), this.scopeAnnotationType);
        if (attributes != null) {
            // 是否为单例的bean
            metadata.setScopeName(attributes.getString("value"));
            // 是否创建bean的代理类
            ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
            if (proxyMode == ScopedProxyMode.DEFAULT) {
                // 默认不创建bean的代理
                proxyMode = this.defaultProxyMode;
            }
            metadata.setScopedProxyMode(proxyMode);
        }
    }
    return metadata;
}
5.3.1、获取注解属性值
// 如果有配置注解,最后会通过process方法检索注释属性
static AnnotationAttributes retrieveAnnotationAttributes(@Nullable Object annotatedElement, Annotation annotation,
                                                         boolean classValuesAsString, boolean nestedAnnotationsAsMap) {

    Class<? extends Annotation> annotationType = annotation.annotationType();
    AnnotationAttributes attributes = new AnnotationAttributes(annotationType);

    // 获取注解的所有方法,并将每个方法都加入到attributeMethodsCache缓存中,再次解析相同注解时可直接获取
    for (Method method : getAttributeMethods(annotationType)) {
        try {
            // 执行注解方法,获取返回值
            Object attributeValue = method.invoke(annotation);
            Object defaultValue = method.getDefaultValue();
            // 判断返回值是否 = 默认值
            if (defaultValue != null && ObjectUtils.nullSafeEquals(attributeValue, defaultValue)) {
                attributeValue = new DefaultValueHolder(defaultValue);
            }
            // 根据classValuesAsString和nestedAnnotationsAsMap处理属性值
            attributes.put(method.getName(),
                           adaptValue(annotatedElement, attributeValue, classValuesAsString, nestedAnnotationsAsMap));
        }
        catch (Throwable ex) {
            if (ex instanceof InvocationTargetException) {
                Throwable targetException = ((InvocationTargetException) ex).getTargetException();
                rethrowAnnotationConfigurationException(targetException);
            }
            throw new IllegalStateException("Could not obtain annotation attribute value for " + method, ex);
        }
    }

    return attributes;
}

5.4、生成bean定义名称

public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
    if (definition instanceof AnnotatedBeanDefinition) {
        // 1.根据注解确定Bean名称(当前注解及其递归父类注解是@Component注解,使用注解的value属性值作为bean名称)
        String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
        // 2.获取的名称字符串长度大于0,且不只包含空格
        if (StringUtils.hasText(beanName)) {
            // Explicit bean name found.
            return beanName;
        }
    }
    // Fallback: generate a unique default bean name.
    // 3.获取当前类bean定义中的类信息名称,将类的短名称作为bean的默认名称
    return buildDefaultBeanName(definition, registry);
}
5.4.1、根据注解确定名称
// 根据注解value属性值确定Bean名称
protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {
    AnnotationMetadata amd = annotatedDef.getMetadata();
    Set<String> types = amd.getAnnotationTypes();
    String beanName = null;
    for (String type : types) {
        // 1.获取注解type的每个属性值(map键值对),此处逻辑同解析@Scope
        AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);
        // 2.校验当前注解及其继承的注解中是否有@Component,并且attributes属性值键值对中包含value属性
        if (attributes != null && isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) {
            Object value = attributes.get("value");
            if (value instanceof String) {
                String strVal = (String) value;
                if (StringUtils.hasLength(strVal)) {
                    if (beanName != null && !strVal.equals(beanName)) {
                        throw new IllegalStateException("Stereotype annotations suggest inconsistent " +
                                                        "component names: '" + beanName + "' versus '" + strVal + "'");
                    }
                    // 3.将value属性值设置为bean名称
                    beanName = strVal;
                }
            }
        }
    }
    return beanName;
}
5.4.2、获取注解及其继承注解的名称
// 获取注解composed上标注的注解,及其继承的所有注解后去重
private static Set<String> getMetaAnnotationTypes(AnnotatedElement element, @Nullable Annotation composed) {
    if (composed == null) {
        return Collections.emptySet();
    }

    try {
        final Set<String> types = new LinkedHashSet<>();
        // 查找逻辑同@Scope
        searchWithGetSemantics(composed.annotationType(), null, null, null, new SimpleAnnotationProcessor<Object>(true) {

            // process的实现
            @Override
            @Nullable
            public Object process(@Nullable AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) {
                types.add(annotation.annotationType().getName());
                return CONTINUE;
            }
        }, new HashSet<>(), 1);
        return types;
    }
    catch (Throwable ex) {
        AnnotationUtils.rethrowAnnotationConfigurationException(ex);
        throw new IllegalStateException("Failed to introspect annotations on " + element, ex);
    }
}
5.4.3、判断是否为可自定义名称的注解
protected boolean isStereotypeWithNameValue(String annotationType,
                                            Set<String> metaAnnotationTypes, @Nullable Map<String, Object> attributes) {

    // 本身是@Component、@ManagedBean、@Named三者之一,或者注解继承的注解是三者之一
    boolean isStereotype = annotationType.equals(COMPONENT_ANNOTATION_CLASSNAME) ||
        metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME) ||
        annotationType.equals("javax.annotation.ManagedBean") ||
        annotationType.equals("javax.inject.Named");

    return (isStereotype && attributes != null && attributes.containsKey("value"));
}
5.4.4、构建默认bean名称
// 未自定义名称生成默认名称
protected String buildDefaultBeanName(BeanDefinition definition) {
    String beanClassName = definition.getBeanClassName();
    Assert.state(beanClassName != null, "No bean class name set");
    String shortClassName = ClassUtils.getShortName(beanClassName);
    // 字符串首字母小写
    return Introspector.decapitalize(shortClassName);
}

5.5、注册bean定义

5.5.1、生成代理bean定义
// 1.注册原始bean定义;2.返回代理bean定义
static BeanDefinitionHolder applyScopedProxyMode(
    ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {

    ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
    // 1. 未配置或者配置属性值为NO的直接返回
    if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
        return definition;
    }
    // 2. 配置是否为CGLIB生成代理
    boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
    // 3. 创建代理的bean定义
    return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
}
5.5.2、创建代理bean定义
// definition为类的bean定义信息及类名称的封装,registry为ioc容器,proxyTargetClass是否是cglib代理
public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition,
                                                     BeanDefinitionRegistry registry, boolean proxyTargetClass) {

    String originalBeanName = definition.getBeanName();
    BeanDefinition targetDefinition = definition.getBeanDefinition();
    // 1.生成新bean名称,用于注册原bean定义:(scopedTarget. + 原bean名称)
    String targetBeanName = getTargetBeanName(originalBeanName);

    // 2.创建代理bean定义(bean的class为org.springframework.aop.scope.ScopedProxyFactoryBean)
    RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
    // 3.设置代理bean定义的bean名称和bean定义(bean定义还是原bean定义)
    proxyDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, targetBeanName));
    // 3.1.给代理bean定义中设置原始的bean定义信息(通过BeanDefinitionResource封装)
    proxyDefinition.setOriginatingBeanDefinition(targetDefinition);
    proxyDefinition.setSource(definition.getSource());
    proxyDefinition.setRole(targetDefinition.getRole());
    proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);
    // 4.是JDK还是CGLIB的代理,true为CGLIB
    if (proxyTargetClass) {
        targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
    }
    else {
        proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
    }

    // 设置自动装配候选,默认为true
    proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
    // 设置是否为首选装配目标,默认为false
    proxyDefinition.setPrimary(targetDefinition.isPrimary());
    if (targetDefinition instanceof AbstractBeanDefinition) {
        proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
    }

    // 忽略原始bean,不使其自动装配,以及不作为首选被装配
    targetDefinition.setAutowireCandidate(false);
    targetDefinition.setPrimary(false);

    // 5.在bean定义工厂中注册原始bean定义,使用新名称
    registry.registerBeanDefinition(targetBeanName, targetDefinition);

    // 6.将代理bean定义作为主bean定义返回
    return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
}
5.5.3、注册bean定义
// definitionHolder可能是原bean定义(AnnotatedGenericBeanDefinition),也可能是代理bean定义(RootBeanDefinition)
public static void registerBeanDefinition(
    BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    throws BeanDefinitionStoreException {

    // Register bean definition under primary name.
    String beanName = definitionHolder.getBeanName();
    // 注册bean定义
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // Register aliases for bean name, if any.
    // 如果有,注册bean的别名
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        for (String alias : aliases) {
            registry.registerAlias(beanName, alias);
        }
    }
}
5.5.3.1、注册bean定义的核心方法
  • org.springframework.beans.factory.support.DefaultListableBeanFactory
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    throws BeanDefinitionStoreException {

    Assert.hasText(beanName, "Bean name must not be empty");
    Assert.notNull(beanDefinition, "BeanDefinition must not be null");

    // 1.校验bean定义(方法重载,作用暂时未知)
    if (beanDefinition instanceof AbstractBeanDefinition) {
        try {
            ((AbstractBeanDefinition) beanDefinition).validate();
        } catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                                                   "Validation of bean definition failed", ex);
        }
    }
	
    // 2.从bean定义map中获取当前注册的bean定义
    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    
    // 3.标识已注册过
    if (existingDefinition != null) {
        if (!isAllowBeanDefinitionOverriding()) {
            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                                                   "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
                                                   "': There is already [" + existingDefinition + "] bound.");
        } else if (existingDefinition.getRole() < beanDefinition.getRole()) {
            // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
            if (logger.isWarnEnabled()) {
                logger.warn("Overriding user-defined bean definition for bean '" + beanName +
                            "' with a framework-generated bean definition: replacing [" +
                            existingDefinition + "] with [" + beanDefinition + "]");
            }
        } else if (!beanDefinition.equals(existingDefinition)) {
            if (logger.isInfoEnabled()) {
                logger.info("Overriding bean definition for bean '" + beanName +
                            "' with a different definition: replacing [" + existingDefinition +
                            "] with [" + beanDefinition + "]");
            }
        } else {
            if (logger.isDebugEnabled()) {
                logger.debug("Overriding bean definition for bean '" + beanName +
                             "' with an equivalent definition: replacing [" + existingDefinition +
                             "] with [" + beanDefinition + "]");
            }
        }
        this.beanDefinitionMap.put(beanName, beanDefinition);
    } else {
        // 4.校验alreadyCreated集合是否为空,如果bean实例化过一次,bean名称就会被记录在alreadyCreated列表中
        if (hasBeanCreationStarted()) {
            // Cannot modify startup-time collection elements anymore (for stable iteration)
            synchronized (this.beanDefinitionMap) {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
                updatedDefinitions.addAll(this.beanDefinitionNames);
                updatedDefinitions.add(beanName);
                this.beanDefinitionNames = updatedDefinitions;
                if (this.manualSingletonNames.contains(beanName)) {
                    Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
                    updatedSingletons.remove(beanName);
                    this.manualSingletonNames = updatedSingletons;
                }
            }
        } else {
            // 5. 注册bean定义,即放入工厂的属性map中
            this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
            this.manualSingletonNames.remove(beanName);
        }
        this.frozenBeanDefinitionNames = null;
    }

    // 6.如果已经存在了一个Definition或者根据bean名称能找到已经实例化完成的bean对象,那么就将这个以前的bean相关的信息都重置掉
    if (existingDefinition != null || containsSingleton(beanName)) {
        resetBeanDefinition(beanName);
        // configurationFrozen默认值false
    } else if (isConfigurationFrozen()) {
        clearByTypeCache();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring通过扫描指定的包路径来查找bean定义,并将它们注册到应用程序上下文中。Spring使用`@ComponentScan`注解来指定需要扫描的包路径。当使用`@ComponentScan`注解时,Spring将扫描所有被`@Component`、`@Service`、`@Repository`和`@Controller`注解的类,并将它们注册bean。 例如,以下代码演示了如何在Spring中使用`@ComponentScan`注解扫描名为`com.example`的包下的所有bean定义: ```java @Configuration @ComponentScan("com.example") public class AppConfig { // ... } ``` 除了`@ComponentScan`注解外,还可以使用`@Bean`注解手动注册bean,或者使用XML配置文件来定义bean。 ### 回答2: Spring框架通过Bean扫描机制可以自动检测和加载应用程序中的Bean。 Spring会在应用程序的类路径上扫描指定的包或类,寻找被Spring管理的Bean。这个过程通常在应用程序启动时发生,Spring会搜索并加载符合条件的类,并将其注册Bean定义Spring框架提供了几种方式来配置Bean的扫描路径。 首先,可以通过使用@ComponentScan注解来开启Bean的自动扫描。在配置类上加上@ComponentScan注解,并指定需要扫描的包路径,Spring框架将会递归地扫描这些包,查找被@Component、@Service、@Repository、@Controller等注解修饰的类,并将其注册Bean。 其次,可以使用XML配置文件来进行扫描Bean。在配置文件中使用<context:component-scan>元素,并设置base-package属性为需要扫描的包路径,Spring框架会自动扫描该包下所有被标记的类,并加载注册Bean。 除此之外,还可以使用基于Java的配置方式,通过编写配置类来定义Bean的扫描路径。在配置类上使用@Configuration和@ComponentScan注解,指定需要扫描的包路径,Spring框架会自动搜索并加载满足条件的类。 总之,无论是通过注解还是XML配置文件,Spring框架可以通过不同的方式来扫描Bean,从而实现自动加载和注册。这样可以避免手动配置每个Bean的信息,提高开发效率,使应用程序更加灵活和可扩展。 ### 回答3: Spring框架通过使用不同的机制来扫描和注册bean。 首先,Spring可以通过基于XML的配置文件来扫描bean。在XML配置文件中,我们可以使用`<bean>`元素来定义一个bean,并通过`id`或`name`属性来标识它。通过在`<bean>`元素中配置适当的信息,如类的全限定名、构造函数参数和属性值,Spring可以实例化和管理这些bean。然后,通过在XML配置文件中使用`<context:component-scan>`元素,可以使Spring自动扫描指定路径下的所有带有特定注解的类,并将它们注册bean。 其次,Spring还可以通过基于注解的方式来扫描bean。通过在类上使用`@Component`注解或其派生注解(如`@Controller`、`@Service`、`@Repository`等),我们可以指示Spring将该类注册为一个bean。同时,通过使用`@Autowired`注解,我们可以将其他依赖的bean自动注入到当前bean中,实现依赖注入的功能。在启动Spring应用程序时,Spring会自动扫描指定路径下的所有类,并将被注解标记的类注册bean。 最后,Spring还支持自定义扫描和注册bean的机制。我们可以实现`BeanDefinitionRegistryPostProcessor`接口来编写自定义bean扫描器,通过编程方式将类注册bean。我们可以根据自己的需求定义扫描路径、过滤条件等,实现更加灵活的bean扫描和注册逻辑。 总结起来,Spring可以通过XML配置文件、基于注解的方式以及自定义扫描器等多种机制来扫描和注册bean,从而实现对应用程序中的组件的管理和控制。这些机制使开发人员能够以更加便捷和灵活的方式管理和使用bean。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值