ConfigurationClassPostProcessor processConfigBeanDefinitions方法解析

  1   1     public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
  2   2         List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
  3   3         String[] candidateNames = registry.getBeanDefinitionNames();
  4   4         //candidateNames包含spring定义的内部配置类、springboot启动的的主类的名称和springcloud用到的配置类,比如:feignClientsConfiguration
  5   5         //springboot启动的的主类在这里就会被找出并在下面的代码中被解析
  6   6         for (String beanName : candidateNames) {
  7   7             BeanDefinition beanDef = registry.getBeanDefinition(beanName);
  8   8             if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
  9   9                 if (logger.isDebugEnabled()) {
 10  10                     logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
 11  11                 }
 12  12             }
 13  13             //判断该beanDef的类是否是通过注解标记的配置类
 14  14             else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
 15  15                 configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
 16  16             }
 17  17         }
 18  18 
 19  19         // Return immediately if no @Configuration classes were found
 20  20         if (configCandidates.isEmpty()) {
 21  21             return;
 22  22         }
 23  23 
 24  24         // Sort by previously determined @Order value, if applicable
 25  25         configCandidates.sort((bd1, bd2) -> {
 26  26             int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
 27  27             int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
 28  28             return Integer.compare(i1, i2);
 29  29         });
 30  30 
 31  31         // Detect any custom bean name generation strategy supplied through the enclosing application context
 32  32         //判断是否有开发人员自定义的bean的命名方式,基本不会自定义
 33  33         //因为BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; beanFactory=DefaultListBeanFactory 
 34  34         //而且一般DefaultListBeanFactory会实现SingletonBeanRegistry,所以能进来
 35  35         SingletonBeanRegistry sbr = null;
 36  36         if (registry instanceof SingletonBeanRegistry) {
 37  37             sbr = (SingletonBeanRegistry) registry;
 38  38             if (!this.localBeanNameGeneratorSet) {
 39  39                 BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
 40  40                         AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
 41  41                 if (generator != null) {
 42  42                     this.componentScanBeanNameGenerator = generator;
 43  43                     this.importBeanNameGenerator = generator;
 44  44                 }
 45  45             }
 46  46         }
 47  47 
 48  48         if (this.environment == null) {
 49  49             this.environment = new StandardEnvironment();
 50  50         }
 51  51 
 52  52         // Parse each @Configuration class
 53  53         ConfigurationClassParser parser = new ConfigurationClassParser(
 54  54                 this.metadataReaderFactory, this.problemReporter, this.environment,
 55  55                 this.resourceLoader, this.componentScanBeanNameGenerator, registry);
 56  56 
 57  57         Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
 58  58         Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
 59  59         //对candidates进行循环解析
 60  60         do {
 61  61             //解析对springboot的主类,这里开始全面解析开发者的写的bean类
 62  62             parser.parse(candidates);
 63  63             parser.validate();
 64  64 
 65  65             Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
 66  66             configClasses.removeAll(alreadyParsed);
 67  67 
 68  68             // Read the model and create bean definitions based on its content
 69  69             if (this.reader == null) {
 70  70                 this.reader = new ConfigurationClassBeanDefinitionReader(
 71  71                         registry, this.sourceExtractor, this.resourceLoader, this.environment,
 72  72                         this.importBeanNameGenerator, parser.getImportRegistry());
 73  73             }
 74  74             //将@Import导入的类、@Bean、@ImportResource 实现ImportBeanDefinitionRegistrar接口的类转换为beanDefinition
 75  75             this.reader.loadBeanDefinitions(configClasses);
 76  76             alreadyParsed.addAll(configClasses);
 77  77 
 78  78             candidates.clear();
 79  79             //如果大于,说明在解析candidates的过程中有新的candidateNames,
 80  80             //找到新加入的candidateNames,组成新的未解析的candidateNames
 81  81             if (registry.getBeanDefinitionCount() > candidateNames.length) {
 82  82                 String[] newCandidateNames = registry.getBeanDefinitionNames();
 83  83                 Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
 84  84                 Set<String> alreadyParsedClasses = new HashSet<>();
 85  85                 for (ConfigurationClass configurationClass : alreadyParsed) {
 86  86                     alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
 87  87                 }
 88  88                 for (String candidateName : newCandidateNames) {
 89  89                     if (!oldCandidateNames.contains(candidateName)) {
 90                      //通过RootBeanDefinition 注入的bean 那么这个类的beanDefinition就是RootBeanDefinition
 91                     //如果是通过扫描@Component或者@Import ,那么这个类默认的beanDefinition就是AnnotationGenericBeanDefinition了。
 92                     //有些地方会对这2种不同的beanDefinition进行不同的处理
 93  90                         BeanDefinition bd = registry.getBeanDefinition(candidateName);
 94  91                         if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
 95  92                                 !alreadyParsedClasses.contains(bd.getBeanClassName())) {
 96  93                             candidates.add(new BeanDefinitionHolder(bd, candidateName));
 97  94                         }
 98  95                     }
 99  96                 }
100  97                 candidateNames = newCandidateNames;
101  98             }
102  99         }
103 100         while (!candidates.isEmpty());
104 101 
105 102         // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
106 103         if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
107 104             sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
108 105         }
109 106 
110 107         if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
111 108             // Clear cache in externally provided MetadataReaderFactory; this is a no-op
112 109             // for a shared cache since it'll be cleared by the ApplicationContext.
113 110             ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
114 111         }
115 112     }

 

posted @ 2021-04-28 15:29  龙之谷2019  阅读(88)  评论(0编辑  收藏  举报