Spring源码分析-Bean解析加载为BeanDefiniton(注解方式)

58 阅读2分钟

测试入口

用源码里的测试接口

image.png

@Test
void SPR8434() {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(UserServiceImpl.class, Foo.class);
    assertThat(ctx.getBean(UserServiceImpl.class).object).isNotNull();
    ctx.close();
}

AnnotationConfigApplicationContext

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(UserServiceImpl.class, Foo.class)进入构造方法

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();
    register(componentClasses);
    refresh();
}

this()

public AnnotationConfigApplicationContext() {
    StartupStep createAnnotatedBeanDefReader = getApplicationStartup().start("spring.context.annotated-bean-reader.create");
    this.reader = new AnnotatedBeanDefinitionReader(this);
    createAnnotatedBeanDefReader.end();
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}
  • 3行,创建一个注解的BeanDefiniton读取器
  • 5行,创建一个Bean的扫描器

register(componentClasses);

public void register(Class<?>... componentClasses) {
    Assert.notEmpty(componentClasses, "At least one component class must be specified");
    StartupStep registerComponentClass = getApplicationStartup().start("spring.context.component-classes.register")
          .tag("classes", () -> Arrays.toString(componentClasses));
    this.reader.register(componentClasses);
    registerComponentClass.end();
}

第5行进入 register 方法 注册一个或多个要处理的组件类。

public void register(Class<?>... componentClasses) {
    for (Class<?> componentClass : componentClasses) {
       registerBean(componentClass);
    }
}

registerBean(componentClass)

public void registerBean(Class<?> beanClass) {
    doRegisterBean(beanClass, null, null, null, null);
}

doRegisterBean(beanClass, null, null, null, null)

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
       @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
       @Nullable BeanDefinitionCustomizer[] customizers) {

    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
       return;
    }

    abd.setAttribute(ConfigurationClassUtils.CANDIDATE_ATTRIBUTE, Boolean.TRUE);
    abd.setInstanceSupplier(supplier);
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

    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));
          }
       }
    }
    if (customizers != null) {
       for (BeanDefinitionCustomizer customizer : customizers) {
          customizer.customize(abd);
       }
    }

    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
  • 5行,将bean包装成AnnotatedGenericBeanDefinition
  • 6行,判断是否需要跳过处理,@Conditional注解的一些匹配
  • 10行,当设置为BooleanTRUE时,此属性表示默认情况下,在“lite”模式下
  • 11行,指定用于创建 Bean 实例的回调,作为声明性指定的工厂方法的替代方法,如果设置了这样的回调,它将覆盖任何其他构造函数或工厂方法元数据。但是,bean 属性填充和潜在的注释驱动注入仍将照常应用。
  • 13行,设置作用域singleton
  • 14行,获取bean 名称
  • 36行,包装成BeanDefinitionHolder
  • 37行,判断是否需要创建代理
  • 38行,注册BeanDefinition
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
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);
       }
    }
}

7行进入

@Override
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 abd) {
       try {
          abd.validate();
       }
       catch (BeanDefinitionValidationException ex) {
          throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                "Validation of bean definition failed", ex);
       }
    }

    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
    if (existingDefinition != null) {
       if (!isBeanDefinitionOverridable(beanName)) {
          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 (isAlias(beanName)) {
          String aliasedName = canonicalName(beanName);
          if (!isBeanDefinitionOverridable(aliasedName)) {
             if (containsBeanDefinition(aliasedName)) {  // alias for existing bean definition
                throw new BeanDefinitionOverrideException(
                      beanName, beanDefinition, getBeanDefinition(aliasedName));
             }
             else {  // alias pointing to non-existing bean definition
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                      "Cannot register bean definition for bean '" + beanName +
                      "' since there is already an alias for bean '" + aliasedName + "' bound.");
             }
          }
          else {
             removeAlias(beanName);
          }
       }
       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);
    }
    else if (isConfigurationFrozen()) {
       clearByTypeCache();
    }
}
  • 78行,放入DefaultListableBeanFactory 的private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256)中
  • 79行,放入DefaultListableBeanFactory的private volatile List beanDefinitionNames = new ArrayList<>(256)中
  • 注解方式将Bean解析为BeanDefinition并加载到工厂中结束。