前言
ConfigurationClassPostProcessor实现了BeanDefinitionRegistryPostProcessor接口,该类会在AbstractApplicationContext#refresh 中的第5步时进行调用.由于其postProcessBeanDefinitionRegistry 实现过程非常复杂,因此单拿一篇进行分析
解析
ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry 代码如下:
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry);
}
2件事
根据BeanDefinitionRegistry,生成registryId 加入到registriesPostProcessed中.registriesPostProcessed是为了做去重的判断,当重复对一个BeanDefinitionRegistry进行处理时,则会抛出IllegalStateException.
调用processConfigBeanDefinitions 进行类的加载.代码如下:
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>(); // 1. 获取已经注册的bean名称 String[] candidateNames = registry.getBeanDefinitionNames(); for (String beanName : candidateNames) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { // 1.1. 如果BeanDefinition 中的configurationClass 属性为full 或者lite ,则意味着已经处理过了,直接跳过 if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } // 1.2. 判断对应bean是否为配置类,如果是,则加入到configCandidates else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } // Return immediately if no @Configuration classes were found // 1.3 如果不存在配置类,则直接return if (configCandidates.isEmpty()) { return; } // Sort by previously determined @Order value, if applicable // 2. 对configCandidates 进行 排序,按照@Order 配置的值进行排序 Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() { @Override public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) { int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition()); int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition()); return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0; } }); // Detect any custom bean name generation strategy supplied through the enclosing application context // 3. 如果BeanDefinitionRegistry 是SingletonBeanRegistry 子类的话,由于我们当前传入的是DefaultListableBeanFactory,是 // SingletonBeanRegistry 的子类。因此会将registry强转为SingletonBeanRegistry SingletonBeanRegistry sbr = null; if (registry instanceof SingletonBeanRegistry) { sbr = (SingletonBeanRegistry) registry; if (!this.localBeanNameGeneratorSet && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) { // 如果localBeanNameGeneratorSet 等于false 并且SingletonBeanRegistry 中有 id 为 org.springframework.context.annotation.internalConfigurationBeanNameGenerator // 的bean .则将componentScanBeanNameGenerator,importBeanNameGenerator 赋值为 该bean. BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR); this.componentScanBeanNameGenerator = generator; this.importBeanNameGenerator = generator; } } // Parse each @Configuration class // 4. 实例化ConfigurationClassParser 为了解析 各个配置类 ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); // 实例化2个set,candidates 用于将之前加入的configCandidates 进行去重 // alreadyParsed 用于判断是否处理过 Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates); Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size()); // 5. 进行解析 do { parser.parse(candidates); parser.validate(); Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses()); configClasses.removeAll(alreadyParsed); // Read the model and create bean definitions based on its content if (this.reader == null) { this.reader = new ConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); candidates.clear(); if (registry.getBeanDefinitionCount() > candidateNames.length) { String[] newCandidateNames = registry.getBeanDefinitionNames(); Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames)); Set<String> alreadyParsedClasses = new HashSet<String>(); 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; } } while (!candidates.isEmpty()); // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes // 6. if (sbr != null) { if (!sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) { // 如果SingletonBeanRegistry 不包含org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry // 则注册一个,bean 为 ImportRegistry. 一般都会进行注册的 sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); } } // 7. 清除缓存 if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) { ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache(); } }
7件事:
获取已经注册的bean名称,进行遍历
- 如果BeanDefinition 中的configurationClass 属性为full 或者lite ,则意味着已经处理过了,直接跳过
- 判断对应bean是否为配置类,如果是,则加入到configCandidates.
- 如果不存在配置类,则直接return
- 对configCandidates 进行 排序,按照@Order 配置的值进行排序
如果BeanDefinitionRegistry 是SingletonBeanRegistry 子类的话,由于我们当前传入的是DefaultListableBeanFactory,是 SingletonBeanRegistry 的子类。因此会将registry强转为SingletonBeanRegistry.
- 如果localBeanNameGeneratorSet 等于false 并且SingletonBeanRegistry 中有 id 为 org.springframework.context.annotation.internalConfigurationBeanNameGenerator的bean .则将componentScanBeanNameGenerator,importBeanNameGenerator 赋值为 该bean.
- 实例化ConfigurationClassParser 为了解析各个配置类.实例化2个set,candidates 用于将之前加入的configCandidates 进行去重,alreadyParsed 用于判断是否处理过
进行解析
- 调用ConfigurationClassParser#parse进行解析
- 将解析过的配置类加入到configClasses,并将configClasses去重已经处理过的,以防止重复加载
- 如果reader为null,则实例化ConfigurationClassBeanDefinitionReader
- 调用ConfigurationClassBeanDefinitionReader#loadBeanDefinitions 进行加载,并加入到alreadyParsed中,用于去重
- 将candidates进行清空,如果registry中注册的bean的数量 大于 之前获得的数量,则意味着在解析过程中又新加入了很多,那么就需要对其进行解析
- 如果SingletonBeanRegistry 不包含org.springframework.context.annotation.ConfigurationClassPostProcessor.importRegistry,则注册一个,bean 为 ImportRegistry. 一般都会进行注册的
- 清除缓存
1.2 判断对应bean是否为配置类 调用的是ConfigurationClassUtils#checkConfigurationClassCandidate.代码如下:
public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) { // 1. 获取类名,如果类名不存在则返回false String className = beanDef.getBeanClassName(); if (className == null) { return false; } // 2. 获得AnnotationMetadata AnnotationMetadata metadata; if (beanDef instanceof AnnotatedBeanDefinition && className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) { // Can reuse the pre-parsed metadata from the given BeanDefinition... // 2.1 如果BeanDefinition 是 AnnotatedBeanDefinition的实例,并且className 和 BeanDefinition中 的元数据 的类名相同 // 则直接从BeanDefinition 获得Metadata metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata(); } else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) { // Check already loaded Class if present... // since we possibly can't even load the class file for this Class. // 2.2 如果BeanDefinition 是 AnnotatedBeanDefinition的实例,并且beanDef 有 beanClass 属性存在 // 则实例化StandardAnnotationMetadata Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass(); metadata = new StandardAnnotationMetadata(beanClass, true); } else { try { // 2.3 否则 通过MetadataReaderFactory 中的MetadataReader 进行读取 MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className); metadata = metadataReader.getAnnotationMetadata(); } catch (IOException ex) { if (logger.isDebugEnabled()) { logger.debug("Could not find class file for introspecting configuration annotations: " + className, ex); } return false; } } // 3. if (isFullConfigurationCandidate(metadata)) { // 3.1 如果存在Configuration 注解,则为BeanDefinition 设置configurationClass属性为full beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL); } else if (isLiteConfigurationCandidate(metadata)) { // 3.2 如果AnnotationMetadata 中有Component,ComponentScan,Import,ImportResource 注解中的任意一个,或者存在 被@bean 注解的方法,则返回true. // 则设置configurationClass属性为lite beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE); } else { // 3.3 返回false return false; } // It's a full or lite configuration candidate... Let's determine the order value, if any. // 4. 如果该类被@Order所注解,则设置order属性为@Order的值 Map<String, Object> orderAttributes = metadata.getAnnotationAttributes(Order.class.getName()); if (orderAttributes != null) { beanDef.setAttribute(ORDER_ATTRIBUTE, orderAttributes.get(AnnotationUtils.VALUE)); } return true; }
5件事:
- 获取类名,如果类名不存在则返回false
获得AnnotationMetadata
- 如果BeanDefinition 是 AnnotatedBeanDefinition的实例,并且className 和 BeanDefinition中的元数据的类名相同,则直接从BeanDefinition 获得Metadata
- 如果BeanDefinition 是 AnnotatedBeanDefinition的实例,并且beanDef 有 beanClass属性存在,则实例化StandardAnnotationMetadata
- 否则 通过MetadataReaderFactory 中的MetadataReader 进行读取
进行判断
- 如果存在Configuration 注解,则为BeanDefinition 设置configurationClass属性为full.
- 如果AnnotationMetadata 中有Component,ComponentScan,Import,ImportResource 注解中的任意一个,或者存在 被@bean 注解的方法,则返回true.
- 否则,返回false
- 如果该类被@Order所注解,则设置order属性为@Order的值
- 返回true.
5.1 调用的是ConfigurationClassParser#parse,代码如下:
public void parse(Set<BeanDefinitionHolder> configCandidates) { this.deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>(); for (BeanDefinitionHolder holder : configCandidates) { BeanDefinition bd = holder.getBeanDefinition(); try { if (bd instanceof AnnotatedBeanDefinition) { parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName()); } else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) { parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName()); } else { parse(bd.getBeanClassName(), holder.getBeanName()); } } catch (BeanDefinitionStoreException ex) { throw ex; } catch (Throwable ex) { throw new BeanDefinitionStoreException( "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex); } } processDeferredImportSelectors(); }
3件事
- 实例化deferredImportSelectors
- 遍历configCandidates ,进行处理.根据BeanDefinition 的类型 做不同的处理,一般都会调用ConfigurationClassParser#parse 进行解析
- 处理ImportSelect
其中第2步 执行的代码如下:
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException { processConfigurationClass(new ConfigurationClass(metadata, beanName)); }
最终调用
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException { // 1. 判断是否应该被跳过 if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) { return; } // 2. 处理Imported 的情况 ConfigurationClass existingClass = this.configurationClasses.get(configClass); if (existingClass != null) { if (configClass.isImported()) { if (existingClass.isImported()) { existingClass.mergeImportedBy(configClass); } // Otherwise ignore new imported config class; existing non-imported class overrides it. return; } else { // Explicit bean definition found, probably replacing an import. // Let's remove the old one and go with the new one. this.configurationClasses.remove(configClass); for (Iterator<ConfigurationClass> it = this.knownSuperclasses.values().iterator(); it.hasNext();) { if (configClass.equals(it.next())) { it.remove(); } } } } // Recursively process the configuration class and its superclass hierarchy. SourceClass sourceClass = asSourceClass(configClass); do { // 3. 递归调用进行解析 sourceClass = doProcessConfigurationClass(configClass, sourceClass); } while (sourceClass != null); // 4. 添加到configurationClasses中 this.configurationClasses.put(configClass, configClass); }
4件事:
判断是否应该被跳过.通过调用ConditionEvaluator#shouldSkip实现的,代码如下:
public boolean shouldSkip(AnnotatedTypeMetadata metadata, ConfigurationPhase phase) { // 1. 如果这个类没有被@Conditional注解所修饰,不会skip if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) { return false; } // 2. 如果参数中沒有设置条件注解的生效阶段 if (phase == null) { // 是配置类的话直接使用PARSE_CONFIGURATION阶段 if (metadata instanceof AnnotationMetadata && ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) { return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION); } // 否则使用REGISTER_BEAN阶段 return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN); } List<Condition> conditions = new ArrayList<Condition>(); // 要解析的配置类的条件集合 // 3. 获取配置类的条件注解得到条件数据,并添加到集合中 for (String[] conditionClasses : getConditionClasses(metadata)) { for (String conditionClass : conditionClasses) { Condition condition = getCondition(conditionClass, this.context.getClassLoader()); conditions.add(condition); } } AnnotationAwareOrderComparator.sort(conditions); // 4. 遍历conditions,进行判断 for (Condition condition : conditions) { ConfigurationPhase requiredPhase = null; if (condition instanceof ConfigurationCondition) { requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase(); } if (requiredPhase == null || requiredPhase == phase) { // 阶段不满足条件的话,返回true并跳过这个bean的解析 if (!condition.matches(this.context, metadata)) { return true; } } } return false; }
4件事
- 如果这个类没有被@Conditional注解所修饰,不会skip,返回false
如果参数中沒有设置条件注解的生效阶段
- 是配置类的话直接使用PARSE_CONFIGURATION阶段,递归调用shouldSkip 进行判断
- 否则使用REGISTER_BEAN阶段,递归调用shouldSkip 进行判断
- 获取配置类的条件注解得到条件数据,并添加到集合中
- 遍历conditions,进行判断,如果阶段不满足条件的话,返回true并跳过这个bean的解析
- 处理Imported 的情况
- 递归调用进行解析
- 添加到configurationClasses中
其中第三步,代码如下:
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { // 1. Recursively process any member (nested) classes first 处理内部类 processMemberClasses(configClass, sourceClass); // 2. Process any @PropertySource annotations 处理@PropertySource for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), PropertySources.class, org.springframework.context.annotation.PropertySource.class)) { if (this.environment instanceof ConfigurableEnvironment) { processPropertySource(propertySource); } else { logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment"); } } // 3. Process any @ComponentScan annotations 处理@ComponentScan Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { for (AnnotationAttributes componentScan : componentScans) { // The config class is annotated with @ComponentScan -> perform the scan immediately // 3.1 进行扫描 Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); // Check the set of scanned definitions for any further config classes and parse recursively if needed // 3.2 依次遍历扫描的配置类进行解析 for (BeanDefinitionHolder holder : scannedBeanDefinitions) { if (ConfigurationClassUtils.checkConfigurationClassCandidate( holder.getBeanDefinition(), this.metadataReaderFactory)) { parse(holder.getBeanDefinition().getBeanClassName(), holder.getBeanName()); } } } } // 4. Process any @Import annotations 处理@Import processImports(configClass, sourceClass, getImports(sourceClass), true); // 5. Process any @ImportResource annotations if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) { AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class); String[] resources = importResource.getStringArray("locations"); // 遍历配置的locations,加入到configClass 中的ImportedResource Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader"); for (String resource : resources) { String resolvedResource = this.environment.resolveRequiredPlaceholders(resource); configClass.addImportedResource(resolvedResource, readerClass); } } // 6. Process individual @Bean methods Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); // 遍历@Bean注释的方法,添加到configClass for (MethodMetadata methodMetadata : beanMethods) { configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } // 7. Process default methods on interfaces processInterfaces(configClass, sourceClass); // 8. Process superclass, if any 如果有父类的话,则返回父类进行进一步的解析 if (sourceClass.getMetadata().hasSuperClass()) { String superclass = sourceClass.getMetadata().getSuperClassName(); if (!superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) { this.knownSuperclasses.put(superclass, configClass); // Superclass found, return its annotation metadata and recurse return sourceClass.getSuperClass(); } } // No superclass -> processing is complete return null; }
8件事
处理内部类.代码如下:
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { // 1. 遍历class中的内部类 for (SourceClass memberClass : sourceClass.getMemberClasses()) { if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) && !memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) { // 2. 如果该内部类是一个配置类,并且该内部类的类名和configClass的类名不相同 if (this.importStack.contains(configClass)) { // 2.1 如果importStack 包含该configClass的化,则意味发生了循环依赖,则会抛出BeanDefinitionParsingException 异常 this.problemReporter.error(new CircularImportProblem(configClass, this.importStack)); } else { // 2.2 否则加入到importStack,调用processConfigurationClass 进行解析 this.importStack.push(configClass); try { processConfigurationClass(memberClass.asConfigClass(configClass)); } finally { this.importStack.pop(); } } } } }
2件事:
- 遍历class中的内部类
如果该内部类是一个配置类,并且该内部类的类名和configClass的类名不相同
- 如果importStack 包含该configClass的化,则意味发生了循环依赖,则会抛出BeanDefinitionParsingException 异常
- 否则加入到importStack,调用processConfigurationClass 进行解析,最后在弹出该configClass.
处理@PropertySource.通过遍历该类中的@PropertySource的注解,如果该类中的environment是ConfigurableEnvironment 子类的话,则调用processPropertySource进行处理.否则打印警告日志.一般都是ConfigurableEnvironment的子类.代码如下:
private void processPropertySource(AnnotationAttributes propertySource) throws IOException { // 1. 解析name、encoding值 String name = propertySource.getString("name"); if (!StringUtils.hasLength(name)) { name = null; } String encoding = propertySource.getString("encoding"); if (!StringUtils.hasLength(encoding)) { encoding = null; } // 2. 解析value(数组)以及ignoreResourceNotFound值 String[] locations = propertySource.getStringArray("value"); Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required"); boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound"); // 3. 解析factory,如果该值没有配置,默认为PropertySourceFactory则直接实例化DefaultPropertySourceFactory类,否则开始实例化自定义的类 Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory"); PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ? DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass)); for (String location : locations) { try { // 4.1 对location进行SPEL表达式的解析。比如当前的配置环境中有一个属性为app=shareniu,我们配置的location为${app}最终值为shareniu。通过这里的处理逻辑可以知道location支持多环境的切换以及表达式的配置 String resolvedLocation = this.environment.resolveRequiredPlaceholders(location); // 4.2 使用资源加载器resourceLoader将resolvedLocation抽象为Resource Resource resource = this.resourceLoader.getResource(resolvedLocation); // 4.3 调用addPropertySource属性进行处理。将指定的资源处理之后,添加到当前springboot运行的环境中 addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding))); } catch (IllegalArgumentException ex) { // 5. 如果上述的任意步骤报错,则开始查找ignoreResourceNotFound的值,如果该值为treu,则忽略异常,否则直接报错 // Placeholders not resolvable if (ignoreResourceNotFound) { if (logger.isInfoEnabled()) { logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage()); } } else { throw ex; } } catch (IOException ex) { // Resource not found when trying to open it if (ignoreResourceNotFound && (ex instanceof FileNotFoundException || ex instanceof UnknownHostException)) { if (logger.isInfoEnabled()) { logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage()); } } else { throw ex; } } } }
5件事:
- 解析name、encoding值
- 解析value(数组)以及ignoreResourceNotFound值
- 解析factory,如果该值没有配置,默认为PropertySourceFactory则直接实例化DefaultPropertySourceFactory类,否则开始实例化自定义的类
遍历配置的locations进行处理
- 对location进行SPEL表达式的解析。比如当前的配置环境中有一个属性为app=shareniu,我们配置的location为${app}最终值为shareniu。通过这里的处理逻辑可以知道location支持多环境的切换以及表达式的配置
- 使用资源加载器resourceLoader将resolvedLocation抽象为Resource
- 调用addPropertySource属性进行处理。将指定的资源处理之后,添加到当前springboot运行的环境中
5.如果上述的任意步骤报错,则开始查找ignoreResourceNotFound的值,如果该值为treu,则忽略异常,否则直接报错
处理@ComponentScan,通过遍历该类上的@ComponentScan 注解,并且通过ConditionEvaluator#shouldSkip判断后
依次通过ComponentScanAnnotationParser#parse进行扫描。最终调用ClassPathBeanDefinitionScanner#doScan.代码如下:
protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>(); for (String basePackage : basePackages) { // 扫描basePackage路径下的java文件 Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { // 解析scope属性 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { // 如果是AnnotatedBeanDefinition类型,则检查常用注解:如lazy等 AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } // 检查当前bean是否已经注册 if (checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); // 如果当前bean是用于生成代理的bean那么需要进一步处理 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }
- 遍历basePackages,通过findCandidateComponents方法扫描basePackage路径下的java文件
如果扫描到文件的话,则遍历之.
- 解析scope属性
- 生成beanName.
如果该 BeanDefinition 是AbstractBeanDefinition 的子类的话,则调用postProcessBeanDefinition为其设置默认值.代码如下:
protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) { beanDefinition.applyDefaults(this.beanDefinitionDefaults); if (this.autowireCandidatePatterns != null) { beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName)); } }
为其设置默认值.
public void applyDefaults(BeanDefinitionDefaults defaults) { setLazyInit(defaults.isLazyInit());//false setAutowireMode(defaults.getAutowireMode());//AUTOWIRE_NO setDependencyCheck(defaults.getDependencyCheck());//DEPENDENCY_CHECK_NONE setInitMethodName(defaults.getInitMethodName());// null setEnforceInitMethod(false); setDestroyMethodName(defaults.getDestroyMethodName());//null setEnforceDestroyMethod(false); }
- 如果autowireCandidatePatterns 不等于null的话,则设置AutowireCandidate.
- 如果该BeanDefinition是AnnotatedBeanDefinition的子类,则调用AnnotationConfigUtils#processCommonDefinitionAnnotations,检查常用注解:如lazy等
检查当前bean是否已经注册,如果没有注册的话,则
- 生成BeanDefinitionHolder
如果当前bean是用于生成代理的bean那么需要进一步处理,代码如下:
static BeanDefinitionHolder applyScopedProxyMode( ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) { ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode(); if (scopedProxyMode.equals(ScopedProxyMode.NO)) { return definition; } boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS); return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass); }
由于一般ScopedProxyMode都是NO,因此也就不会生成代理
- 添加到beanDefinitions中
- 向BeanDefinitionRegistry进行注册
- 依次遍历扫描的配置类进行递归解析.最终又会调用ConfigurationClassParser#processConfigurationClass
处理@Import.代码如下:
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, Collection<SourceClass> importCandidates, boolean checkForCircularImports) throws IOException { // 1. 如果importCandidates为空,则直接return if (importCandidates.isEmpty()) { return; } // 2. 进行循环依赖的检查 if (checkForCircularImports && isChainedImportOnStack(configClass)) { this.problemReporter.error(new CircularImportProblem(configClass, this.importStack)); } else { this.importStack.push(configClass); try { // 3. 如果不存在循环依赖,则依次遍历处理之 for (SourceClass candidate : importCandidates) { if (candidate.isAssignable(ImportSelector.class)) { // 3.1 如果是ImportSelector的子类 // Candidate class is an ImportSelector -> delegate to it to determine imports Class<?> candidateClass = candidate.loadClass(); // 则实例化后,调用ParserStrategyUtils#invokeAwareMethods ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class); ParserStrategyUtils.invokeAwareMethods( selector, this.environment, this.resourceLoader, this.registry); if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) { // 3.2 如果当前类是DeferredImportSelector 的实现,则加入到deferredImportSelectors this.deferredImportSelectors.add( new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector)); } else { // 3.3 如果不是,则调用processImports 进行处理. String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata()); Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames); processImports(configClass, currentSourceClass, importSourceClasses, false); } } else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) { // Candidate class is an ImportBeanDefinitionRegistrar -> // delegate to it to register additional bean definitions // 如果是ImportBeanDefinitionRegistrar的子类,则实例化后,调用ParserStrategyUtils#invokeAwareMethods, // 添加到configClass中 Class<?> candidateClass = candidate.loadClass(); ImportBeanDefinitionRegistrar registrar = BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class); ParserStrategyUtils.invokeAwareMethods( registrar, this.environment, this.resourceLoader, this.registry); configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata()); } else { // Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar -> // process it as an @Configuration class // 3. 否则,加入到importStack后调用processConfigurationClass 进行处理. this.importStack.registerImport( currentSourceClass.getMetadata(), candidate.getMetadata().getClassName()); processConfigurationClass(candidate.asConfigClass(configClass)); } } } catch (BeanDefinitionStoreException ex) { throw ex; } catch (Throwable ex) { throw new BeanDefinitionStoreException( "Failed to process import candidates for configuration class [" + configClass.getMetadata().getClassName() + "]", ex); } finally { this.importStack.pop(); } } }
- 如果@Import注解不存在的话,则直接return.
- 进行循环依赖的检查,如果存在循环依赖的话,则直接抛出异常
加入importStack中,用于循环依赖的检查,依次遍历 @Import
如果是ImportSelector的子类,则实例化后,调用ParserStrategyUtils#invokeAwareMethods.
- 如果当前类是DeferredImportSelector 的实现,则加入到deferredImportSelectors
- 如果不是,则调用processImports 进行处理.
如果是ImportBeanDefinitionRegistrar的子类,则实例化后,调用ParserStrategyUtils#invokeAwareMethods,添加到configClass中
- 否则,加入到importStack后调用processConfigurationClass 进行处理.
最后,从importStack栈顶元素.
其中ParserStrategyUtils#invokeAwareMethods,代码如下:
public static void invokeAwareMethods(Object parserStrategyBean, Environment environment, ResourceLoader resourceLoader, BeanDefinitionRegistry registry) { if (parserStrategyBean instanceof Aware) { if (parserStrategyBean instanceof BeanClassLoaderAware) { ClassLoader classLoader = (registry instanceof ConfigurableBeanFactory ? ((ConfigurableBeanFactory) registry).getBeanClassLoader() : resourceLoader.getClassLoader()); ((BeanClassLoaderAware) parserStrategyBean).setBeanClassLoader(classLoader); } if (parserStrategyBean instanceof BeanFactoryAware && registry instanceof BeanFactory) { ((BeanFactoryAware) parserStrategyBean).setBeanFactory((BeanFactory) registry); } if (parserStrategyBean instanceof EnvironmentAware) { ((EnvironmentAware) parserStrategyBean).setEnvironment(environment); } if (parserStrategyBean instanceof ResourceLoaderAware) { ((ResourceLoaderAware) parserStrategyBean).setResourceLoader(resourceLoader); } } }
如果parserStrategyBean 是Aware 的子类
- 如果parserStrategyBean是BeanClassLoaderAware的子类,则为其注入ClassLoader
- 如果parserStrategyBean是BeanFactoryAware的子类并且registry是BeanFactory的子类,则为其注入BeanFactory
- 如果parserStrategyBean是EnvironmentAware的子类,则为其注入Environment
- 如果parserStrategyBean是ResourceLoaderAware的子类,则为其注入ResourceLoader
- 否则不进行处理.
- 处理@ImportResource,通过获得其@ImportResource,获得locations值后, 遍历配置的locations,加入到configClass 中的ImportedResource.
- 处理被@Bean注解的方法,遍历@Bean注释的方法,添加到configClass中的BeanMethod
处理接口中被@Bean注解默认方法,代码如下:
private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { // 1. 遍历sourceClass 的接口 for (SourceClass ifc : sourceClass.getInterfaces()) { // 2. 获得被@bean注释的方法 Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(ifc); for (MethodMetadata methodMetadata : beanMethods) { if (!methodMetadata.isAbstract()) { // A default method or other concrete method on a Java 8+ interface... // 3. 如果不是抽象方法的话,则加入到configClass的BeanMethod configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } } // 4. 递归处理 processInterfaces(configClass, ifc); } }
- 遍历sourceClass 的接口
- 获得被@bean注释的方法
- 如果不是抽象方法的话,则加入到configClass的BeanMethod
- 递归调用processInterfaces,看其父接口中是否存在被@bean注解的方法,直到父接口不存在.
- 如果有父类的话,则返回父类进行进一步的解析,否则返回null
5.4 调用的是ConfigurationClassBeanDefinitionReader#loadBeanDefinitions,代码如下:
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) { // 1. 实例化TrackedConditionEvaluator TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator(); // 2. 遍历configurationModel,依次调用loadBeanDefinitionsForConfigurationClass for (ConfigurationClass configClass : configurationModel) { loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator); } }
2件事:
- 实例化TrackedConditionEvaluator
遍历configurationModel,依次调用loadBeanDefinitionsForConfigurationClass进行加载.代码如下:
private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) { // 1. 使用条件注解判断是否需要跳过这个配置类 if (trackedConditionEvaluator.shouldSkip(configClass)) { String beanName = configClass.getBeanName(); // 1.1 跳过配置类的话在Spring容器中移除bean的注册 if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) { this.registry.removeBeanDefinition(beanName); } // 1.2 从importRegistry 进行删除. this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName()); return; } if (configClass.isImported()) { // 2. 如果自身是被@Import注释所import的,注册自己 registerBeanDefinitionForImportedConfigurationClass(configClass); } // 3. 遍历BeanMethods,依次对其进行注册. for (BeanMethod beanMethod : configClass.getBeanMethods()) { loadBeanDefinitionsForBeanMethod(beanMethod); } // 4.注册@ImportResource注解注释的资源文件中的bean loadBeanDefinitionsFromImportedResources(configClass.getImportedResources()); // 5. 注册@Import注解中的ImportBeanDefinitionRegistrar接口的registerBeanDefinitions loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars()); }
5件事:
- 使用条件注解判断是否需要跳过这个配置类,如果需要跳过的话,则Spring容器中移除该bean.并且从importRegistry删除.然后直接return.否则执行第2步.
如果自身是被@Import注解所import的,则调用registerBeanDefinitionForImportedConfigurationClass进行注册.代码如下:
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) { // 1. 根据configClass中配置的AnnotationMetadata 实例化AnnotatedGenericBeanDefinition AnnotationMetadata metadata = configClass.getMetadata(); AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata); // 2 进行属性的设置 // 2.1 解析该configClass的Scope ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef); configBeanDef.setScope(scopeMetadata.getScopeName()); // 2.2 生成bean的id String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry); // 2.3 设置bean的一些属性,如LazyInit,Primary等 AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata); // 3. 生成BeanDefinitionHolder,并对其尝试进行代理,最后向registry进行注册 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition()); configClass.setBeanName(configBeanName); if (logger.isDebugEnabled()) { logger.debug("Registered bean definition for imported class '" + configBeanName + "'"); } }
3件事
- 根据configClass中配置的AnnotationMetadata 实例化AnnotatedGenericBeanDefinition
进行属性的设置
- 解析该configClass的Scope
- 生成bean的id
- 设置bean的一些属性,如LazyInit,Primary等
- 生成BeanDefinitionHolder,并对其尝试进行代理,最后向registry进行注册
遍历BeanMethods,依次对其调用loadBeanDefinitionsForBeanMethod进行注册.代码如下:
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) { // 1. 获得声明该BeanMethod的ConfigurationClass ConfigurationClass configClass = beanMethod.getConfigurationClass(); // 获得BeanMethod的MethodMetadata和methodName MethodMetadata metadata = beanMethod.getMetadata(); String methodName = metadata.getMethodName(); // Do we need to mark the bean as skipped by its condition? // 2. 进行判断,是否应该跳过处理 // 2.1 如果ConditionEvaluator#shouldSkip返回true,则添加到configClass的skippedBeanMethods中,return if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) { configClass.skippedBeanMethods.add(methodName); return; } // 2.2 如果configClass的skippedBeanMethods包含该methodName的话,不进行处理, if (configClass.skippedBeanMethods.contains(methodName)) { return; } // Consider name and any aliases // 3. 从@Bean 中获得配置的names,如果names不为空的话,则第一个为bean的id,否则该方法名字作为bean的id AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class); List<String> names = new ArrayList<String>(Arrays.asList(bean.getStringArray("name"))); String beanName = (!names.isEmpty() ? names.remove(0) : methodName); // Register aliases even when overridden // 4. 将names 当做别名进行注册 for (String alias : names) { this.registry.registerAlias(beanName, alias); } // Has this effectively been overridden before (e.g. via XML)? // 5. 如果存在重复定义的情况,则直接return if (isOverriddenByExistingDefinition(beanMethod, beanName)) { return; } // 6. 实例化ConfigurationClassBeanDefinition ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata); beanDef.setResource(configClass.getResource()); beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource())); if (metadata.isStatic()) { // 6.1 如果该方法是静态的,则将methodName设置为工厂方法 // static @Bean method beanDef.setBeanClassName(configClass.getMetadata().getClassName()); beanDef.setFactoryMethodName(methodName); } else { // instance @Bean method // 6.2 如果是实例方法的话,则将configClass的BeanName设置为FactoryBeanName,methodName设置为UniqueFactoryMethodName beanDef.setFactoryBeanName(configClass.getBeanName()); beanDef.setUniqueFactoryMethodName(methodName); } // 6.3 设置AutowireMode 为 构造器注入 beanDef.setAutowireMode(RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); // 设置skipRequiredCheck属性为true. beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE); // 6.4 进行一些常用的属性设置 AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata); Autowire autowire = bean.getEnum("autowire"); if (autowire.isAutowire()) { beanDef.setAutowireMode(autowire.value()); } String initMethodName = bean.getString("initMethod"); if (StringUtils.hasText(initMethodName)) { // 设置 InitMethod beanDef.setInitMethodName(initMethodName); } String destroyMethodName = bean.getString("destroyMethod"); if (destroyMethodName != null) { // 设置 DestroyMethod beanDef.setDestroyMethodName(destroyMethodName); } // Consider scoping // 6.5 设置ScopedProxyMode ScopedProxyMode proxyMode = ScopedProxyMode.NO; AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class); if (attributes != null) { beanDef.setScope(attributes.getString("value")); proxyMode = attributes.getEnum("proxyMode"); if (proxyMode == ScopedProxyMode.DEFAULT) { proxyMode = ScopedProxyMode.NO; } } // Replace the original bean definition with the target one, if necessary // 6.6 如果ScopedProxyMode 不等于NO,则生成代理 BeanDefinition beanDefToRegister = beanDef; if (proxyMode != ScopedProxyMode.NO) { BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy( new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS); beanDefToRegister = new ConfigurationClassBeanDefinition( (RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata); } if (logger.isDebugEnabled()) { logger.debug(String.format("Registering bean definition for @Bean method %s.%s()", configClass.getMetadata().getClassName(), beanName)); } // 7. 进行注册 this.registry.registerBeanDefinition(beanName, beanDefToRegister); }
7件事:
- 获得声明该BeanMethod的ConfigurationClass,获得BeanMethod的MethodMetadata和methodName
进行判断,是否应该跳过处理
- 如果ConditionEvaluator#shouldSkip返回true,则添加到configClass的skippedBeanMethods中,return
- 如果configClass的skippedBeanMethods包含该methodName的话,不进行处理,
- 从@Bean 中获得配置的names,如果names不为空的话,则第一个为bean的id,否则该方法名字作为bean的id
- 将names 当做别名进行注册
- 如果存在重复定义的情况,则直接return
实例化ConfigurationClassBeanDefinition
- 如果该方法是静态的,则将methodName设置为工厂方法
- 否则如果是实例方法的话,则将configClass的BeanName设置为FactoryBeanName,methodName设置为UniqueFactoryMethodName
- 设置AutowireMode 为 构造器注入,设置skipRequiredCheck属性为true.
- 进行一些常用的属性设置
- 设置 InitMethod
- 设置 DestroyMethod
- 设置ScopedProxyMode,如果ScopedProxyMode 不等于NO,则生成代理
- 进行注册
注册@ImportResource注解注释的资源文件中的bean.代码如下:
private void loadBeanDefinitionsFromImportedResources( Map<String, Class<? extends BeanDefinitionReader>> importedResources) { Map<Class<?>, BeanDefinitionReader> readerInstanceCache = new HashMap<Class<?>, BeanDefinitionReader>(); // 1. 遍历importedResources for (Map.Entry<String, Class<? extends BeanDefinitionReader>> entry : importedResources.entrySet()) { String resource = entry.getKey(); Class<? extends BeanDefinitionReader> readerClass = entry.getValue(); // Default reader selection necessary? // 2. 选择BeanDefinitionReader if (BeanDefinitionReader.class == readerClass) { if (StringUtils.endsWithIgnoreCase(resource, ".groovy")) { // When clearly asking for Groovy, that's what they'll get... // 2.1 如果是.groovy,则为GroovyBeanDefinitionReader readerClass = GroovyBeanDefinitionReader.class; } else { // Primarily ".xml" files but for any other extension as well // 2.2 否则为XmlBeanDefinitionReader,一般都是XmlBeanDefinitionReader readerClass = XmlBeanDefinitionReader.class; } } // 3. 尝试从readerInstanceCache中获取对应的BeanDefinitionReader BeanDefinitionReader reader = readerInstanceCache.get(readerClass); if (reader == null) {// 如果不存在,则实例化一个 try { // Instantiate the specified BeanDefinitionReader reader = readerClass.getConstructor(BeanDefinitionRegistry.class).newInstance(this.registry); // Delegate the current ResourceLoader to it if possible if (reader instanceof AbstractBeanDefinitionReader) { // 如果reader是AbstractBeanDefinitionReader的子类的话,这个肯定是... AbstractBeanDefinitionReader abdr = ((AbstractBeanDefinitionReader) reader); abdr.setResourceLoader(this.resourceLoader); abdr.setEnvironment(this.environment); } // 然后放入readerInstanceCache,以防止重复实例化. readerInstanceCache.put(readerClass, reader); } catch (Throwable ex) { throw new IllegalStateException( "Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]"); } } // TODO SPR-6310: qualify relative path locations as done in AbstractContextLoader.modifyLocations reader.loadBeanDefinitions(resource);}}
3件事:
- 遍历importedResources
选择BeanDefinitionReader
- 如果是.groovy结尾的话,则为GroovyBeanDefinitionReader
- 否则为XmlBeanDefinitionReader,一般都是XmlBeanDefinitionReader
- 尝试从readerInstanceCache中获取对应的BeanDefinitionReader,如果不存在,则实例化一个,然后放入到readerInstanceCache缓存中
- 调用BeanDefinitionReader#loadBeanDefinitions进行加载.
由于一般情况下都是XmlBeanDefinitionReader,最终会调用XmlBeanDefinitionReader#loadBeanDefinitions进行加载,这部分属于spring加载xml部分了,碍于篇幅,这里就不在展开了,后续会有文章进行分析的.
注册@Import注解中的ImportBeanDefinitionRegistrar接口的registerBeanDefinitions.代码如下:
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) { for (Map.Entry<ImportBeanDefinitionRegistrar, AnnotationMetadata> entry : registrars.entrySet()) { entry.getKey().registerBeanDefinitions(entry.getValue(), this.registry); } }
只是简单的进行注册.
至此关于bean的加载我们就分析完了.