栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

spring源码--bean扫描

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

spring源码--bean扫描

bean扫描postProcessBeanDefinitionRegistry
  1. 遍历ioc中已注册的bd,获取候选配置类

    • @Configuration,设置为full类型配置类
    • @Bean、@Component、@ComponentScan、 @Import、@ImportResource,设置为lite类型配置
    • 解析配置类的@Order,设置BeanDefinition的order属性值
  2. 对候选配置类按@Order排序

  3. 准备BeanNameGenerator和Environment

  4. 初始化parser=ConfigurationClassParser
    主要是初始化ComponentScanAnnotationParser和ConditionEvaluator

  5. 主配置类包装成ConfigurationClass,利用parser开始解析
    不断从主配置类下钻,类似多叉树深度遍历。遍历到叶子节点后加入parser的configurationClasses集合中

    • 利用ConditionEvaluator判断@Conditional是否满足,不满足结束(条件判断阶段为PARSE_CONFIGURATION阶段)
    • 循环解析,因为注解可能在父类上
      • 有内部类,递归第5步

      • @PropertySource

      • 利用ComponentScanAnnotationParser解析@ComponentScan

        • 利用ConditionEvaluator判断@Conditional是否满足,不满足结束(条件判断阶段为REGISTER_BEAN阶段)
        • 初始化scanner=ClassPathBeanDefinitionScanner,默认添加2个includeFilter(@Component、@Configuration、@Controller、@Named、@Service、@Repository注解)
        • 根据@Component的属性设置scanner,默认添加1个execludeFilter(排除自己)
        • 获取扫描包路径,没有指定的话使用配置类的包路径,然后利用scanner扫描(ASM技术)
          a. 先使用execludeFilters、includeFilters、@Condition过滤得到候选bd。
          b. 再过滤候选bd是否非抽象外部类、抽象类(抽象类必须要有@Lookup修饰的方法)
          c. 去重并注册bd。因为bd可能在处理其他@ComponentScan时被扫描过。没重复的bd直接注册到ioc容器中。
        • 检查扫描出的bd还需要递归解析,因为可能上面还有full或lite类型的注解,根据bd中的类名封装成配置类,递归第5步
      • @Import

        • 导入普通类
          把它当成配置类,递归第5步
        • 导入ImportBeanDefinitionRegistrar
          实例化registrar、执行Aware接口方法、把registrar加入配置类的importBeanDefinitionRegistrars中,后续会用到
        • 导入ImportSelector
          实例化selector、执行Aware接口方法、判断是否DeferredImportSelector。
          如果不是DeferredImportSelector,执行selector.selectImports()得到导入的类名集合,再递归@Import步骤。如果是DeferredImportSelector, 把selector加入parser的deferredImportSelectors中,后续会用到
      • @ImportResource
        获取属性指定的reader,保存在配置类的importedResources中,后续会用到

      • @Bean
        将@Bean方法转化为BeanMethod对象,保存在配置类的beanMethods中,后续会用到

      • 处理接口默认方法上的@Bean,类似于@Bean处理

    • 把配置类加入parser的configurationClasses中,底层是个LinkedHashSet,保证了配置类解析顺序
  6. 遍历parser的deferredImportSelectors,执行selectImports()
    这是留给其它框架注册bd的1个入口,比如springboot的自动配置

  7. 遍历parser的configurationClasses,进行bd验证
    a. @Configuration的配置类不能是final
    b. @Bean修饰的方法必须可以重写以支持CGLIB

  8. 初始化reader=ConfigurationClassBeanDefinitionReader

  9. 遍历parser的configurationClasses,利用reader注册剩余的bd

    • 对已扫描注册的bd再一次进行@Conditional判断,如果不满足从 BeanDefinitionRegistry移除。springboot的@ConditionalOnBean就在这儿判断
    • 注册内部类和@Import的普通类
    • 注册@Bean
      a. 初始化bd=ConfigurationClassBeanDefinition。
      b. 非static方法,设置bd的factoryBeanName和factoryMethodName。
      c. static方法,设置bd的beanClass和factoryMethodName。
      d. 设置autowire属性,AUTOWIRE_BY_TYPE、AUTOWIRE_BY_NAME。
      e. 解析@Scope,如果设置了proxyMode则创建1个代理bd。
      f. 解析@Lazy、@Primary、@Role、@DependsOn、@Description
    • 注册@ImportResource导入的
    • 注册ImportBeanDefinitionRegistrar导入的
      遍历配置类的importBeanDefinitionRegistrars,执行registerBeanDefinitions方法去注册bd
bean增postProcessBeanFactory()

判断是否bd是否有@Configuration注解,有就生成1个代理类并setBeanClass。
另外,添加1个处理器ImportAwareBeanPostProcessor

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1035269.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号