Spring Bean 扫描注册 之 AnnotatedBeanDefinitionReader

Spring Bean 扫描注册 之 AnnotatedBeanDefinitionReader

 

 

1、简介

AnnotatedBeanDefinitionReader是干什么的?

  1. 从类对象中获取基本注解信息,创建BeanDefinition对象。
  2. BeanDefinition对象注册到BeanDefinitionRegistry对象中。

由于BeanFactoryApplicationContext的实现类基本上都会实现BeanDefinitionRegistry接口。所以AnnotatedBeanDefinitionReader实际上会将BeanDefinition对象注册到Spring容器中。

这和我们上篇文章介绍的 ClassPathBeanDefinitionScanner 都是注册Bean到 IOC 容器中, 但 AnnotatedBeanDefinitionReader 是基于具体的类注册,ClassPathBeanDefinitionScanner  基于给定的包扫描注册。

 

2、 基本使用

现在有ComponentA

public class ComponentA { }

需要将ComponentA注册到Spring容器中:

// 创建registry  
BeanDefinitionRegistry registry = new DefaultListableBeanFactory();  
// 创建reader,指定registry  
AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(registry);  
// 注册指定类作为bean  
reader.registerBean(ComponentA.class);  
// 打印ComponentA的BeanDefinition信息  
System.out.println(registry.getBeanDefinition("componentA"));

输出结果如下:

Generic bean: class [ComponentA]; scope=singleton; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false;
factoryBeanName=null;
factoryMethodName=null; initMethodName=null; destroyMethodName=null

 

3、源码解读

核心步骤在AnnotatedBeanDefinitionReader#registerBean()方法。registerBean()方法有很多重载的实现,最终都会调用AnnotatedBeanDefinitionReader#doRegisterBean()。

我们先大概看一下它的实现:

private <T> void doRegisterBean(
      Class<T> beanClass,
      @Nullable String name, 
      @Nullable Class<? extends Annotation>[] qualifiers, 
      @Nullable Supplier<T> supplier,  
      @Nullable BeanDefinitionCustomizer[] customizers) {  
   // 根据给定类对象,创建BeanDefinition基本信息
   AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);  
   // 根据@Conditional判断是否应该跳过
   if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {  
      return;  
   }  
   // 指定创建bean的方法
   abd.setInstanceSupplier(supplier);  
   // 指定作用域
   ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);  
   abd.setScope(scopeMetadata.getScopeName());  
   // 生成beanName
   String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));  
   // 指定类对象标注通用的注解:@Lazy、@Primary、@DependsOn、@Role、@Description
   AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);  
   // 指定传参的注解:@Primary、@Lazy等
   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));  
         }  
      }  
   }  
   // BeanDefinition自定义处理拦截
   if (customizers != null) {  
      for (BeanDefinitionCustomizer customizer : customizers) {  
         customizer.customize(abd);  
      }  
   }  
   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);  
   // 判断并创建作用域代理
   definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);  
   // 注册到Spring容器
   BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);  
}

接下来对每个步骤进行深入讲解。

3.1、创建AnnotatedGenericBeanDefinition

AnnotatedGenericBeanDefinitionGenericBeanDefinition的子类。除了GenericBeanDefinitionAbstractBeanDefinition中定义的关于bean的基本信息,AnnotatedGenericBeanDefinition额外存储了类的注解信息:

public AnnotatedGenericBeanDefinition(Class<?> beanClass) {  
   setBeanClass(beanClass);  
   this.metadata = AnnotationMetadata.introspect(beanClass);  
}

沿着构造函数继续深入,可以发现会在AnnotationsScanner#getDeclaredAnnotations()获取注解信息:

static Annotation[] getDeclaredAnnotations(AnnotatedElement source, boolean defensive) {  
   boolean cached = false;  
   Annotation[] annotations = declaredAnnotationCache.get(source);  
   if (annotations != null) {  
      cached = true;  
   }  
   else {  
      annotations = source.getDeclaredAnnotations();  
      if (annotations.length != 0) {  
         boolean allIgnored = true;  
         for (int i = 0; i < annotations.length; i++) {  
            Annotation annotation = annotations[i];  
            if (isIgnorable(annotation.annotationType()) ||  
                  !AttributeMethods.forAnnotationType(annotation.annotationType()).isValid(annotation)) {  
               annotations[i] = null;  
            }  
            else {  
               allIgnored = false;  
            }  
         }  
         annotations = (allIgnored ? NO_ANNOTATIONS : annotations);  
         if (source instanceof Class || source instanceof Member) {  
            declaredAnnotationCache.put(source, annotations);  
            cached = true;  
         }  
      }  
   }  
   if (!defensive || annotations.length == 0 || !cached) {  
      return annotations;  
   }  
   return annotations.clone();  
}

 

3.2、 @Conditional校验

获取基本注解信息后,首先会根据@Conditional注解信息判断是否需要注册这个类对象:

if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {  
   return;  
}

校验的核心源码位于ConditionEvaluator#shouldSkip()方法:

public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, 
                          @Nullable ConfigurationPhase phase) {  
   // 没有标注@Condition,直接返回
   if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {  
      return false;  
   }  
  
   if (phase == null) {  
      // 配置类:类标注@Component/@ComponentScan/@Import/@ImportResource,或方法标注@Bean
      if (metadata instanceof AnnotationMetadata &&  
            ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {  
         return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);  
      }  
      // 普通类
      return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);  
   }  
   // 获取所有@Conditional注解对应的Condition实现类
   List<Condition> conditions = new ArrayList<>();  
   for (String[] conditionClasses : getConditionClasses(metadata)) {  
      for (String conditionClass : conditionClasses) {  
         Condition condition = getCondition(conditionClass, this.context.getClassLoader());  
         conditions.add(condition);  
      }  
   }  
   // 对Condition实现类排序
   AnnotationAwareOrderComparator.sort(conditions);  
   // 遍历Condition实现类,调用其matches()方法进行校验
   for (Condition condition : conditions) {  
      ConfigurationPhase requiredPhase = null;  
      if (condition instanceof ConfigurationCondition) {  
         requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();  
      }  
      if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this.context, metadata)) {  
         return true;  
      }  
   }  
   return false;  
}

总的来说,AnnotatedBeanDefinitionReader会根据标注的@Conditional进行校验,具体校验逻辑位于对应Condition实现类中。

例如@Profile的对应校验实现类为ProfileCondition,校验逻辑为:

public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {  
   // 获取@Profile属性
   MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());  
   if (attrs != null) {  
      // 遍历@Profile属性值
      for (Object value : attrs.get("value")) {  
         // 从environment中获取运行时环境变量进行匹配
         if (context.getEnvironment().acceptsProfiles(Profiles.of((String[]) value))) {  
            return true;  
         }  
      }  
      return false;  
   }  
   return true;  
}

 

3.3、 添加instanceSupplier回调

BeanDefinitioninstanceSupplier属性通常作为创建bean对象的特殊回调。

AbstractAutowireCapableBeanFactory#createBeanInstance()方法中,会根据BeanDefinition中是否有instanceSupplier信息来执行回调:

protected BeanWrapper createBeanInstance(String beanName, 
                                         RootBeanDefinition mbd, 
                                         @Nullable Object[] args) {  
   // 省略……
   Supplier<?> instanceSupplier = mbd.getInstanceSupplier();  
   if (instanceSupplier != null) {  
      return obtainFromSupplier(instanceSupplier, beanName);  
   }  
   // 省略……
}

 

3.4、生成beanName

如果指定名字,则用对应形参值;如果没有指定名字,会生成名字:

String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

 AnnotatedBeanDefinition会调用AnnotationBeanNameGenerator#generateBeanName()方法生成beanName

public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {  
   if (definition instanceof AnnotatedBeanDefinition) {  
      // 根据注解生成beanName
      String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);  
      if (StringUtils.hasText(beanName)) {  
         // Explicit bean name found.  
         return beanName;  
      }  
   }  
   // 根据默认规则生成beanName 
   return buildDefaultBeanName(definition, registry);  
}

AnnotationBeanNameGenerator#determineBeanNameFromAnnotation()方法会获取@Component及其子注解、@ManagedBean@Named注解的value值作为beanName

protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) {  
   // 获取注解类型
   AnnotationMetadata amd = annotatedDef.getMetadata();  
   Set<String> types = amd.getAnnotationTypes();  
   // 遍历注解类型,设置beanName
   String beanName = null;  
   for (String type : types) {  
      // 获取注解信息
      AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type);  
      if (attributes != null) {  
         // 获取元注解信息
         Set<String> metaTypes = this.metaAnnotationTypesCache.computeIfAbsent(type, key -> {  
            Set<String> result = amd.getMetaAnnotationTypes(key);  
            return (result.isEmpty() ? Collections.emptySet() : result);  
         });  
         // 校验元注解是否是@Component、注解是否是@Component、@ManagedBean或@Named
         if (isStereotypeWithNameValue(type, metaTypes, attributes)) {  
            // 获取value属性作为beanName
            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 + "'");  
                  }  
                  beanName = strVal;  
               }  
            }  
         }  
      }  
   }  
   return beanName;  
}

AnnotationBeanNameGenerator#buildDefaultBeanName()方法会根据类名生成beanName

protected String buildDefaultBeanName(BeanDefinition definition) {  
   // 获取全限定类名
   String beanClassName = definition.getBeanClassName();  
   Assert.state(beanClassName != null, "No bean class name set");  
   // 获取类名:根据包名分隔符(.)、CGLIB代理类分隔符($$)和内部类分隔符($)进行字符串处理
   String shortClassName = ClassUtils.getShortName(beanClassName);  
   // 类名处理:如果长度大于1且第一二个字母都是大写(或类名为空),直接返回,否则首字母小写返回
   return Introspector.decapitalize(shortClassName);  
}

 

3.5、通用注解处理

接下来会对一些通用注解进行解析和设置,这里的通用注解包括:@Lazy@Primary@DependsOn@Role@Description

// 解析类对象中的注解信息
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));  
      }  
   }  
}

AnnotationConfigUtils#processCommonDefinitionAnnotations()方法会解析类对象中的通用注解信息:

static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {  
   AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);  
   if (lazy != null) {  
      abd.setLazyInit(lazy.getBoolean("value"));  
   }  
   else if (abd.getMetadata() != metadata) {  
      lazy = attributesFor(abd.getMetadata(), Lazy.class);  
      if (lazy != null) {  
         abd.setLazyInit(lazy.getBoolean("value"));  
      }  
   }  
  
   if (metadata.isAnnotated(Primary.class.getName())) {  
      abd.setPrimary(true);  
   }  
   AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);  
   if (dependsOn != null) {  
      abd.setDependsOn(dependsOn.getStringArray("value"));  
   }  
  
   AnnotationAttributes role = attributesFor(metadata, Role.class);  
   if (role != null) {  
      abd.setRole(role.getNumber("value").intValue());  
   }  
   AnnotationAttributes description = attributesFor(metadata, Description.class);  
   if (description != null) {  
      abd.setDescription(description.getString("value"));  
   }  
}

 

2.6、BeanDefinition自定义处理拦截

接下来,会根据形参的BeanDefinitionCustomizer进行自定义处理,可以修改BeanDefinition的信息:

if (customizers != null) {  
   for (BeanDefinitionCustomizer customizer : customizers) {  
      customizer.customize(abd);  
   }  
}

 

2.7、注册到Spring容器

最后,会将BeanDefinitionHolder信息添加到Spring容器:

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);  
      }  
   }  
}

不同的BeanDefinitionRegistry实现类会有不同的注册逻辑,这里主要介绍DefaultListableBeanFactory的实现。

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);  
      }  
   }  
  
   // 校验beanName是否已存在
   BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);  
   // 如果beanName已存在
   if (existingDefinition != null) {  
      // 如果Spring容器不允许重载BeanDefinition,抛出异常
      if (!isAllowBeanDefinitionOverriding()) {  
         throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);  
      }  
      // 如果Spring容器不允许重载BeanDefinition,会进行覆盖
      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);  
   }  
   // 如果beanName不存在
   else {  
      // 如果Spring容器已经进入创建bean的阶段:加锁进行更新
      if (hasBeanCreationStarted()) {  
         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);  
         }  
      }  
      // 如果Spring容器没有进入创建bean的阶段,即还在注册阶段:直接更新
      else {  
         this.beanDefinitionMap.put(beanName, beanDefinition);  
         this.beanDefinitionNames.add(beanName);  
         removeManualSingletonName(beanName);  
      }  
      this.frozenBeanDefinitionNames = null;  
   }  
   // 如果beanName对应的BeanDefinition和单例对象已经存在:即发生了覆盖
   if (existingDefinition != null || containsSingleton(beanName)) {  
      // 清除该beanName(以及子bean)的mergedBeanDefinition和单例对象缓存
      resetBeanDefinition(beanName);  
   }  
   // 否则,如果Spring容器可以缓存BeanDefinition的元数据
   else if (isConfigurationFrozen()) {  
      // 清除所有allBeanNamesByType和singletonBeanNamesByType缓存(类对象-beanNmae映射的缓存)
      clearByTypeCache();  
   }  
}

 

posted @ 2023-12-02 15:39  邓维-java  阅读(486)  评论(0)    收藏  举报