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 }