配置类需要标注@Configuration却不知原因?那这次就不能给你涨薪喽(中)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 配置类需要标注@Configuration却不知原因?那这次就不能给你涨薪喽(中)
ConfigurationClassParser:
  @Nullable
  protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
    ... // 先解析nested内部类(内部类会存在@Bean方法嘛~)
    ... // 解析@PropertySource资源,加入到environment环境
    ... // 解析@ComponentScan注解,把组件扫描进来
    scannedBeanDefinitions = ComponentScanAnnotationParser.parse(componentScan, ...);
      // 把扫描到的Bean定义信息依旧需要一个个的判断,是否是配置类 
      // 若是配置类,就继续当作一个@Configuration配置类来解析parse() 递归嘛
      for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
        ...
        if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
          parse(bdCand.getBeanClassName(), holder.getBeanName());
        }
      }
    ... // 解析@Import注解
    ... // 解析@ImportResource注解
    ... // 解析当前配置里配置的@Bean方法
    ... // 解析接口默认方法(因为配置类可能实现接口,然后接口默认方法可能标注有@Bean )
    ... // 处理父类(递归,直到父类为java.打头的为止)
  }


这个方法是Spring对配置类解析的最核心步骤,通过它顺带也能够解答你的疑惑了吧:为何你仅需在类上标注一个@Configuration注解即可让它成为一个配置类?因为被Scan扫描进去了嘛~


通过以上两个使用处的分析和对比,对于@Configuration配置类的理解,你至少应该掌握了如下讯息:


@Configuration配置类肯定是个组件,存在于IoC容器里

@Configuration配置类是有主次之分的,主配置类是驱动整个程序的入口,可以是一个,也可以是多个(若存在多个,支持使用@Order排序)

我们平时一般只书写次配置类(而且一般写多个),它一般是借助主配置类的@ComponentScan能力完成加载进而解析的(当然也可能是@Import、又或是被其它次配置类驱动的)

配置类可以存在嵌套(如内部类),继承,实现接口等特性

聊完了最为重要的checkConfigurationClassCandidate()方法,当然还有必要看看ConfigurationClassUtils的另一个工具方法isConfigurationCandidate()。


isConfigurationCandidate()

它是一个public static工具方法,通过给定的注解元数据信息来判断它是否是一个Configuration。


ConfigurationClassUtils:
  static {
    candidateIndicators.add(Component.class.getName());
    candidateIndicators.add(ComponentScan.class.getName());
    candidateIndicators.add(Import.class.getName());
    candidateIndicators.add(ImportResource.class.getName());
  }
  public static boolean isConfigurationCandidate(AnnotationMetadata metadata) {
    // 不考虑接口 or 注解 说明:注解的话也是一种“特殊”的接口哦
    if (metadata.isInterface()) {
      return false;
    }
    // 只要该类上标注有以上4个注解任意一个,都算配置类
    for (String indicator : candidateIndicators) {
      if (metadata.isAnnotated(indicator)) {
        return true;
      }
    }
    // 若一个注解都没标注,那就看有木有@Bean方法 若有那也算配置类
    return metadata.hasAnnotatedMethods(Bean.class.getName());
  }


步骤总结:


  1. 若是接口类型(含注解类型),直接不予考虑,返回false。否则继续判断
  2. 若此类上标注有@Component、@ComponentScan、@Import、@ImportResource任意一个注解,就判断成功返回true。否则继续判断
  3. 到此步,就说明此类上没有标注任何注解。若存在@Bean方法,返回true,否则返回false。


需要特别特别特别注意的是:此方法它的并不考虑@Configuration注解,是“轻量级”判断,这是它和checkConfigurationClassCandidate()方法的最主要区别。当然,后者依赖于前者,依赖它来根据注解元数据判断是否是Lite模式的配置。

Spring 5.2.0版本变化说明


因为本文的讲解和代码均是基于Spring 5.2.2.RELEASE的,而并不是所有小伙伴都会用到这么新的版本。关于此部分的实现,以Spring 5.2.0版本为分界线实现上有些许差异,所以在此处做出说明。



相关文章
|
6月前
|
IDE Java 数据库连接
JAVA注解:那些年,我们错过的代码元数据!
【6月更文挑战第29天】Java注解,非执行代码的元数据,常被误解为注释。其实,它们支持编译时检查(如@Override)、自动生成代码、依赖注入(如Spring)和ORM映射(如Hibernate)。通过自定义注解,如示例中的`@MyAnnotation`,可在运行时通过反射增强方法功能。别再错过注解的力量,让它们提升代码的灵活性和可维护性!
34 0
|
安全 Java 程序员
SCPPO(二十二):读取配置文件---程序猿必不可少的技能
SCPPO(二十二):读取配置文件---程序猿必不可少的技能
|
Java Spring 容器
SpringIOC注入三种方式灵活运用(第十四课)
SpringIOC注入三种方式灵活运用(第十四课)
102 0
|
Java Spring 容器
面试官:@Configuration 和 @Component 注解的区别?大部分人都会答错!
面试官:@Configuration 和 @Component 注解的区别?大部分人都会答错!
133 0
面试官:@Configuration 和 @Component 注解的区别?大部分人都会答错!
|
Java Spring 容器
配置类需要标注@Configuration却不知原因?那这次就不能给你涨薪喽(上)
配置类需要标注@Configuration却不知原因?那这次就不能给你涨薪喽(上)
配置类需要标注@Configuration却不知原因?那这次就不能给你涨薪喽(上)
|
设计模式 Java API
你自我介绍说很懂Spring配置类,那你怎么解释这个现象?(中)
你自我介绍说很懂Spring配置类,那你怎么解释这个现象?(中)
你自我介绍说很懂Spring配置类,那你怎么解释这个现象?(中)
|
Java Spring 容器
你自我介绍说很懂Spring配置类,那你怎么解释这个现象?(下)
你自我介绍说很懂Spring配置类,那你怎么解释这个现象?(下)
你自我介绍说很懂Spring配置类,那你怎么解释这个现象?(下)
|
存储 Java 程序员
你自我介绍说很懂Spring配置类,那你怎么解释这个现象?(上)
你自我介绍说很懂Spring配置类,那你怎么解释这个现象?(上)
你自我介绍说很懂Spring配置类,那你怎么解释这个现象?(上)
|
XML Java 数据库连接
1. 不吹不擂,第一篇就能提升你对Bean Validation数据校验的认知(下)
1. 不吹不擂,第一篇就能提升你对Bean Validation数据校验的认知(下)
1. 不吹不擂,第一篇就能提升你对Bean Validation数据校验的认知(下)
|
Oracle Java 关系型数据库
1. 不吹不擂,第一篇就能提升你对Bean Validation数据校验的认知(上)
1. 不吹不擂,第一篇就能提升你对Bean Validation数据校验的认知(上)
1. 不吹不擂,第一篇就能提升你对Bean Validation数据校验的认知(上)