Spring5源码解析2register方法注册配置类

3次阅读

共计 7223 个字符,预计需要花费 19 分钟才能阅读完成。

接上回已经讲完了 this() 方法,现在来看 register(annotatedClasses); 方法。

// new AnnotationConfigApplicationContext(AppConfig.class); 源码
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
    // 调用默认无参构造器, 里面有一大堆初始化逻辑
    this();

    // 把传入的 Class 进行注册,Class 既可以有 @Configuration 注解, 也可以没有 @Configuration 注解
    // 怎么注册? 委托给了 org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register 方法进行注册
    // 传入 Class 生成  BeanDefinition , 然后通过 注册到 BeanDefinitionRegistry
    register(annotatedClasses);

    // 刷新容器上下文
    refresh();}

register(annotatedClasses) 方法

register(annotatedClasses);方法最后其实是调用了 readerdoRegisterBean(annotatedClass, null, null, null);方法。

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
                        @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
    // 根据传入的 Class 对象生成  AnnotatedGenericBeanDefinition ,
    // AnnotatedGenericBeanDefinition 是 BeanDefinition 的 一个实现类
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
    // 根据 @Conditional 注解, 判断是否需要跳过解析
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}

    abd.setInstanceSupplier(instanceSupplier);
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

    // 解析 Class<T> annotatedClass 是否有通用注解: @Lazy,@Primary,@DependsOn,@Role,@Description
    // 并把解决结果放入 AnnotatedBeanDefinition 中
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

    //Class<? extends Annotation>[] qualifiers 是通过方法调用传入的
    // 上一步是解析 Class 中是否有注解, 这一步是调用方作为参数传入的
    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 {
                //org.springframework.beans.factory.support.AbstractBeanDefinition.qualifiers
                //Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>();
                // 直接放入 map 中
                abd.addQualifier(new AutowireCandidateQualifier(qualifier));
            }
        }
    }
    for (BeanDefinitionCustomizer customizer : definitionCustomizers) {customizer.customize(abd);
    }

    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

    // 将该 Class<T> annotatedClass 转为 BeanDefinition 后, 通过再封装为 BeanDefinitionHolder 对象, 进行 registerBeanDefinition
    //AnnotatedBeanDefinitionReader 中有一个 BeanDefinitionRegistry registry 是通过构造方法传入的
    //new AnnotationConfigApplicationContext(AppConfig.class); AnnotationConfigApplicationContext extends GenericApplicationContext
    // GenericApplicationContext 类 实现了 BeanDefinitionRegistry ,registry 即为 AnnotationConfigApplicationContext
    // GenericApplicationContext 类 内部 是 通过 DefaultListableBeanFactory 来实现 BeanDefinitionRegistry 接口的
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
  1. 根据传入的 class 对象创建AnnotatedGenericBeanDefinitionAnnotatedGenericBeanDefinitionBeanDefinition 的一个实现类。
  2. 根据@Conditional 注解,判断是否需要跳过解析,很明显这里不需要,返回 false,代码继续向下执行。
  3. 根据传入的参数,设置BeanDefinition 的属性
  4. 解析传入的 class 对象是否有通用注解(@Lazy@Primary@DependsOn@Role@Description),并把解析结果放入 AnnotatedBeanDefinition中。
  5. 判断是否有传入 Class<? extends Annotation>[] qualifiers 参数,如果不为 null,则将传入的 qualifiers 参数设置到 BeanDefinition 中。注意,第 4 步解析的是 class 中是否带有通用注解。而这步判断的注解是调用方手动传入的。
  6. 将传入的 class 对象转化为 BeanDefinition后,再将 BeanDefinition 封装到 BeanDefinitionHolder 中(为了方便传参),然后调用 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); 注册该 BeanDefinition
  7. 调用 registerBeanDefinition 方法时传入的 this.registry 对象是 AnnotatedBeanDefinitionReader 的一个属性,它是在构造方法中被初始化的。这个 this.registry 对象其实就是 AnnotationConfigApplicationContext 对象。AnnotationConfigApplicationContext 继承了 GenericApplicationContextGenericApplicationContext 类实现了 BeanDefinitionRegistry 接口。而在 GenericApplicationContext 类中其实是委托给成员变量 beanFactory 来实现 BeanDefinitionRegistry 接口的。
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {private final DefaultListableBeanFactory beanFactory;
  1. 再来看 registerBeanDefinition 方法。主要是通过 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); 方法将 BeanDefinition 注册到 DefaultListableBeanFactory 中,也就是 spring 容器中。
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
        throws BeanDefinitionStoreException {

    // Register bean definition under primary name.
    String beanName = definitionHolder.getBeanName();
    registry.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);
        }
    }
}

而所谓的注册 BeanDefinition,简单理解就是将BeanDefinition 放到 DefaultListableBeanFactory 对象的 beanDefinitionMap 中。

//org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition 方法源码
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");

    if (beanDefinition instanceof AbstractBeanDefinition) {
        try {((AbstractBeanDefinition) beanDefinition).validate();} catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                    "Validation of bean definition failed", ex);
        }
    }

    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    // 第一次进来 existingDefinition 肯定为 null
    if (existingDefinition != null) {if (!isAllowBeanDefinitionOverriding()) {throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
        } else if (existingDefinition.getRole() < beanDefinition.getRole()) {
            // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
            if (logger.isInfoEnabled()) {
                logger.info("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.isDebugEnabled()) {
                logger.debug("Overriding bean definition for bean'" + beanName +
                        "'with a different definition: replacing [" + existingDefinition +
                        "] with [" + beanDefinition + "]");
            }
        } else {if (logger.isTraceEnabled()) {
                logger.trace("Overriding bean definition for bean'" + beanName +
                        "'with an equivalent definition: replacing [" + existingDefinition +
                        "] with [" + beanDefinition + "]");
            }
        }
        this.beanDefinitionMap.put(beanName, beanDefinition);
    } else {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;
                removeManualSingletonName(beanName);
            }
        } else {
            // Still in startup registration phase
            this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
            removeManualSingletonName(beanName);
        }
        this.frozenBeanDefinitionNames = null;
    }

    if (existingDefinition != null || containsSingleton(beanName)) {resetBeanDefinition(beanName);
    }
}

运行完 register(annotatedClasses); 方法之后,spring 容器中还没有实例化 bean,而只是注册了一些BeanDefinition。(注册的是 Spring 内部一些 postProcessor 和我们代码传入的 AppConfig 类)。


源码学习笔记 GITHUB 仓库地址:https://github.com/shenjianen…

欢迎关注公众号:Coder 小黑

正文完
 0