转载

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

接上回已经讲完了 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类)。

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

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

欢迎关注公众号:Coder小黑

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

原文  https://segmentfault.com/a/1190000020549843
正文到此结束
Loading...