【SpringBoot源码分析】-Bean的加载过程 (11)

此处处理的是在配置类中具有@Bean注解的方法

// ① Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) { // ② configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } // ④ private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { for (SourceClass ifc : sourceClass.getInterfaces()) { Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(ifc); for (MethodMetadata methodMetadata : beanMethods) { if (!methodMetadata.isAbstract()) { // A default method or other concrete method on a Java 8+ interface... configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } } processInterfaces(configClass, ifc); } } // ⑤ if (sourceClass.getMetadata().hasSuperClass()) { String superclass = sourceClass.getMetadata().getSuperClassName(); if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) { this.knownSuperclasses.put(superclass, configClass); // Superclass found, return its annotation metadata and recurse return sourceClass.getSuperClass(); } }

① - 获取所有具有@Bean注解的方法
② - 将获取到的方法包装为BeanMethod对象(表示一个具有@Bean注解的@Configuration类的方法)保存到当前配置类的beanMethods属性中
④ - 处理接口中具有@Bean注解的方法
⑤ - 处理父类中具有@Bean注解的方法

取出@Configuration

直接从Parser中取出之前解析时缓存的配置类,因为这段代码在do-while循环中,因此首先移除已处理的。

Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses()); configClasses.removeAll(alreadyParsed); 构建BeanDefinitionReader

若Reader为空,则创建,用于读取配置中的BeanDefinition

if (this.reader == null) { this.reader = new ConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } @Configuration读取BeanDefinition

前面对各种注解的的解析最终并没有处理解析的结果,而是将其放在了ConfigurationClass对象的属性当中存储,在这里将通过Reader来处理这
些不同来源的BeanDefinition。

this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) { TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator(); // ① for (ConfigurationClass configClass : configurationModel) { // ② loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator); } }

① - 遍历所有的@Configuration
② - 从@Configuration读取BeanDefinition

private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) { // ① if (trackedConditionEvaluator.shouldSkip(configClass)) { String beanName = configClass.getBeanName(); if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) { this.registry.removeBeanDefinition(beanName); } this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName()); return; } // ② if (configClass.isImported()) { registerBeanDefinitionForImportedConfigurationClass(configClass); } // ③ for (BeanMethod beanMethod : configClass.getBeanMethods()) { loadBeanDefinitionsForBeanMethod(beanMethod); } // ④ loadBeanDefinitionsFromImportedResources(configClass.getImportedResources()); // ⑤ loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars()); }

① - 是否需要跳过
② - 当前配置类本身是否通过@Import导入,若有则将自身注册为BeanDefinition
③ - 当前配置类中是否有@Bean注解修饰的方法,若有则处理
④ - 加载从@ImportResource导入的XML文件中定义的Bean
⑤ - 加载从@Import导入的BeanDefinition

合并已处理的BeanDefinition // ① String[] candidateNames = registry.getBeanDefinitionNames(); if (registry.getBeanDefinitionCount() > candidateNames.length) { // ② String[] newCandidateNames = registry.getBeanDefinitionNames(); // ③ Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames)); // ④ Set<String> alreadyParsedClasses = new HashSet<>(); // ⑤ for (ConfigurationClass configurationClass : alreadyParsed) { alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); } // ⑥ for (String candidateName : newCandidateNames) { // ⑦ if (!oldCandidateNames.contains(candidateName)) { // ⑧ BeanDefinition bd = registry.getBeanDefinition(candidateName); if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) { candidates.add(new BeanDefinitionHolder(bd, candidateName)); } } } // ⑨ candidateNames = newCandidateNames; }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfsdy.html