一、Bean工厂的后置处理器

  Bean工厂的后置处理器:BeanFactoryPostProcessor(触发时机:bean定义注册之后bean实例化之前)和BeanDefinitionRegistryPostProcessor(触发时机:bean定义注册之前),所以可以在Bean工厂的后置处理器中修改Bean的定义信息,比如是否延迟加载、加入一些新的Bean的定义信息等

  Bean工厂的后置处理器类继承图:

二、调用Bean工厂的后置处理器

  invokeBeanFactoryPostProcessors(beanFactory)方法:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//传入Bean工厂并获取容器中的Bean工厂后置处理器(注意这里Bean工厂后置处理器还没有初始化)
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}

  进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())方法:

final class PostProcessorRegistrationDelegate {
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { Set<String> processedBeans = new HashSet<>(); //判断我们的beanFactory是否实现了BeanDefinitionRegistry
if (beanFactory instanceof BeanDefinitionRegistry) {
//强行把beanFactory转为BeanDefinitionRegistry
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//保存BeanFactoryPostProcessor类型的后置处理器
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//保存BeanDefinitionRegistryPostProcessor类型的后置处理器
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); //循环我们传递进来的beanFactoryPostProcessors
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//判断我们的后置处理器是不是BeanDefinitionRegistryPostProcessor
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
//进行强制转化
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//调用它的后置方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//添加到我们用于保存的BeanDefinitionRegistryPostProcessor的集合中
registryProcessors.add(registryProcessor);
}
else {//若没有实现BeanDefinitionRegistryPostProcessor接口,那么他就是BeanFactoryPostProcessor 把当前的后置处理器加入到regularPostProcessors中
regularPostProcessors.add(postProcessor);
}
} //定义一个集合用户保存当前准备创建的BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); //第一步:去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称
for (String ppName : postProcessorNames) {
//判断是否实现了PriorityOrdered接口的
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//同时也加入到processedBeans集合中去
processedBeans.add(ppName);
}
}
//对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//把他加入到用于保存到registryProcessors中
registryProcessors.addAll(currentRegistryProcessors);
/**
* 在这里典型的BeanDefinitionRegistryPostProcessor就是ConfigurationClassPostProcessor
* 用于进行bean定义的加载 比如我们的包扫描,@import等
*/
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//调用完之后,马上clear
currentRegistryProcessors.clear(); //下一步 又去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称
for (String ppName : postProcessorNames) {
//表示没有被处理过,且实现了Ordered接口的
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
//显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//同时也加入到processedBeans集合中去
processedBeans.add(ppName);
}
}
//对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//把他加入到用于保存到registryProcessors中
registryProcessors.addAll(currentRegistryProcessors);
//调用他的后置处理方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//调用完之后,马上clear
currentRegistryProcessors.clear(); //调用没有实现任何优先级接口的BeanDefinitionRegistryPostProcessor
//定义一个重复处理的开关变量 默认值为true
boolean reiterate = true;
//第一次就可以进来
while (reiterate) {
//进入循环马上把开关变量给改为false
reiterate = false;
//去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//循环上一步获取的BeanDefinitionRegistryPostProcessor的类型名称
for (String ppName : postProcessorNames) {
//没有被处理过的
if (!processedBeans.contains(ppName)) {
//显示的调用getBean()的方式获取出该对象然后加入到currentRegistryProcessors集合中去
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//同时也加入到processedBeans集合中去
processedBeans.add(ppName);
//再次设置为true
reiterate = true;
}
}
//对currentRegistryProcessors集合中BeanDefinitionRegistryPostProcessor进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//把他加入到用于保存到registryProcessors中
registryProcessors.addAll(currentRegistryProcessors);
//调用他的后置处理方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//进行clear
currentRegistryProcessors.clear();
} //调用实现了BeanDefinitionRegistryPostProcessor的接口 他是他也同时实现了BeanFactoryPostProcessor的方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//调用BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else { //若当前的beanFactory没有实现了BeanDefinitionRegistry 直接调用beanFactoryPostProcessor接口的方法进行后置处理
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
} //最后一步 获取容器中所有的 BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); //保存BeanFactoryPostProcessor类型实现了priorityOrdered
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//保存BeanFactoryPostProcessor类型实现了Ordered接口的
List<String> orderedPostProcessorNames = new ArrayList<>();
//保存BeanFactoryPostProcessor没有实现任何优先级接口的
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
//processedBeans包含的话,表示在上面处理BeanDefinitionRegistryPostProcessor的时候处理过了
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
//判断是否实现了PriorityOrdered
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
//判断是否实现了Ordered
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
//没有实现任何的优先级接口的
else {
nonOrderedPostProcessorNames.add(ppName);
}
} //先调用BeanFactoryPostProcessor实现了PriorityOrdered接口的
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); //再调用BeanFactoryPostProcessor实现了Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); //调用没有实现任何方法接口的
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}

  第一步:去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称
  String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)  Debug进去看到如下:为什么就一个ConfigurationClassPostProcessor,因为我们自定的BeanDefinitionRegistryPostProcessor还没有被加入到Spring容器中去

  第一步里面的invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)方法:

/**
* Invoke the given BeanDefinitionRegistryPostProcessor beans.
*/
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
//获取容器中的ConfigurationClassPostProcessor的后置处理器进行Bean定义的扫描
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}

  接下来就会调用到org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry方法(很重要):

/**
* Derive further bean definitions from the configuration classes in the registry.
*/
@Override
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);
//真正的解析我们的Bean定义
processConfigBeanDefinitions(registry);
}

  进入到真正的解析processConfigBeanDefinitions方法中:

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//获取Spring IoC容器中目前所有Bean定义的名称
String[] candidateNames = registry.getBeanDefinitionNames(); //循环所有的Bean定义信息
for (String beanName : candidateNames) {
//通过Bean的名称来获取Bean的定义对象
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//判断是否有没有解析过
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//判断是否是配置类
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//添加到候选的配置类集合中
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
} // 若没有找到配置类 直接返回
if (configCandidates.isEmpty()) {
return;
} //对我们的配置类进行Order排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
}); //创建@CompentScan、@Import导入进来的bean名称的生成器
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
//设置@CompentScan导入进来的bean的名称生成器
this.componentScanBeanNameGenerator = generator;
//设置@Import导入进来的bean的名称生成器
this.importBeanNameGenerator = generator;
}
}
} if (this.environment == null) {
this.environment = new StandardEnvironment();
} //创建一个配置类解析器对象
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry); //创建一个集合用于保存我们的配置类BeanDefinitionHolder集合默认长度是配置类集合的长度
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
//创建一个集合用于保存我们的已经解析的配置类,长度默认为解析出来默认的配置类的集合长度
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
//do while
do {
//真正的解析我们的配置类
parser.parse(candidates);
parser.validate(); //解析出来的配置类
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(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();
//判断我们Spring IoC容器中Bean的定义数量是否 > 候选原始的bean定义的个数
if (registry.getBeanDefinitionCount() > candidateNames.length) {
//获取所有的bean定义
String[] newCandidateNames = registry.getBeanDefinitionNames();
//原始的老的候选的bean定义
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;
}
}
//存在没有解析过的 需要循环解析
while (!candidates.isEmpty()); // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
} if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}

  Debug解析:

  进入parser.parse(candidates)方法:

public void parse(Set<BeanDefinitionHolder> configCandidates) {
//用于保存延时的ImportSelectors
this.deferredImportSelectors = new LinkedList<>(); for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
//真正的解析我们的bean定义
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);
}
}
//处理我们延时的DeferredImportSelectors Spring Boot就是通过这步进行spring.factories文件中的自定装配的对象
processDeferredImportSelectors();
}

  Debug解析:

  进入parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName())方法:

/**
* 真正的解析我们的配置类
* @param metadata 配置类的源信息
* @param beanName 当前配置类的beanName
* @throws IOException
*/
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
//把我们的配置类源信息和beanName包装成一个ConfigurationClass对象
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}

  进入processConfigurationClass(new ConfigurationClass(metadata, beanName))方法:

protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
} //获取我们的配置类对象
ConfigurationClass existingClass = this.configurationClasses.get(configClass); if (existingClass != null) {
//传入的配置类是通过其他配置类的Import导入进来的
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);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
} // Recursively process the configuration class and its superclass hierarchy.
SourceClass sourceClass = asSourceClass(configClass);
//真正的进行配置类的解析
do {
//解析我们的配置类
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null); this.configurationClasses.put(configClass, configClass);
}

  进入解析我们的配置类的doProcessConfigurationClass(configClass, sourceClass)方法:

protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException { // Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass); //处理我们的@PropertySources注解的
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");
}
} //接下来解析我们的@ComponentScans注解
//从我们的配置类上解析@ComponentScans的对象集合属性
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
//循环解析(我们解析出来的AnnotationAttributes)
for (AnnotationAttributes componentScan : componentScans) {
//把我们扫描出来的类变为bean定义的集合
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
//循环处理我们包扫描出来的bean定义
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
//判断当前扫描出来的bean定义是不是一个配置类,若是的话 直接进行递归解析
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
//递归解析
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
} //处理@Import
processImports(configClass, sourceClass, getImports(sourceClass), true); //处理@ImportResource
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
} //处理@Bean methods获取到我们配置类中所有标注了@Bean的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
} //处理配置类接口的
processInterfaces(configClass, sourceClass); //处理配置类的父类的
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();
}
} //没有父类解析完成
return null;
}

  Debug解析:

  ① 解析@ComponentScanthis.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName())方法:

public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader); //给扫描器设置beanName的生成器对象
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass)); //设置bean的域代理模型
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
} scanner.setResourcePattern(componentScan.getString("resourcePattern")); //设置ComponentScan对象的includeFilters包含的属性
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
//设置ComponentScan对象的excludeFilters不包含的属性
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
} //是否懒加载
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
} //包路径
Set<String> basePackages = new LinkedHashSet<>();
String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (String pkg : basePackagesArray) {
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
} scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
//真正的进行扫描解析
return scanner.doScan(StringUtils.toStringArray(basePackages));
}

  进入真正的进行扫描解析scanner.doScan(StringUtils.toStringArray(basePackages))方法:

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
//创建bean定义的holder对象用于保存扫描后生成的bean定义对象
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
//循环我们的包路径集合
for (String basePackage : basePackages) {
//找到候选的@Component
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) { ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
//设置我们的beanName
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
//处理@AutoWired相关的
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
//处理jsr250相关的组件
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
//把我们解析出来的组件bean定义注册到Spring IoC容器中
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
//注册到Spring IoC容器中
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}

  Debug解析:

  进过org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan处理,Spring IoC容器中Bean的定义有12个了;

  ② 接下来处理@Import注解导入的Bean组件:

  进入处理@Import注解的processImports(configClass, sourceClass, getImports(sourceClass), true)方法:

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) { if (importCandidates.isEmpty()) {
return;
} if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
//获取我们Import导入进来的所有组件
for (SourceClass candidate : importCandidates) {
//判断该组件是不是实现了ImportSelector的
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
//实例化我们的SelectImport组件
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
//调用相关的aware方法
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
//判断是不是延时的DeferredImportSelectors,是这个类型不进行处理
if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
this.deferredImportSelectors.add(
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
}
else {//不是延时的调用selector的selectImports
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
//反之SelectImport导入进来的又是Import进来的 所以递归解析
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
//判断我们导入的组件是不是ImportBeanDefinitionRegistrar
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
//实例话我们的ImportBeanDefinitionRegistrar对象
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
ParserStrategyUtils.invokeAwareMethods(
registrar, this.environment, this.resourceLoader, this.registry);
//保存我们的ImportBeanDefinitionRegistrar对象
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {//就是一个普通的组件 但是防止我们普通的组件是一个配置类 所以还是直接走了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();
}
}
}

  ③ 接下来处理@ImportSource比如@ImportResource("classpath:circulation-di.xml"),基于xml的(

   ④ 接下来处理@Bean:

  至此解析完成,注意@Import、@ImportSource、@Bean的定义还未注册到Spring IoC的容器中去

  接下来将剩余的Bean定义信息注册到Spring IoC容器中:

  进入真正的把我们解析出来的配置类注册到容器中this.reader.loadBeanDefinitions(configClasses)方法:

public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
//注册我们的配置类到容器中
for (ConfigurationClass configClass : configurationModel) {
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}

  进入loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator)方法:

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;
} //是不是通过@Import导入进来的
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
//是不是通过我们的@Bean导入进来的组件
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
} //是不是通过@ImportResources导入进来的
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
//是不是通过ImportBeanDefinition注解导入进来的
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}

  ① 通过@Import导入进来的执行registerBeanDefinitionForImportedConfigurationClass(configClass)方法:

private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
//获取我们的配置类的源信息
AnnotationMetadata metadata = configClass.getMetadata();
//构建为我们的bean定义
AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
//设置他的scope
ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
configBeanDef.setScope(scopeMetadata.getScopeName());
//获取bean的名称
String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
//处理我们的JRS250组件的
AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata); BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//注册我们的bean定义到我们的容器中
this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
configClass.setBeanName(configBeanName); if (logger.isDebugEnabled()) {
logger.debug("Registered bean definition for imported class '" + configBeanName + "'");
}
}

  ② 通过@Bean导入进来的执行loadBeanDefinitionsForBeanMethod(beanMethod)方法:

private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
ConfigurationClass configClass = beanMethod.getConfigurationClass();
MethodMetadata metadata = beanMethod.getMetadata();
String methodName = metadata.getMethodName(); // Do we need to mark the bean as skipped by its condition?
if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
configClass.skippedBeanMethods.add(methodName);
return;
}
if (configClass.skippedBeanMethods.contains(methodName)) {
return;
} AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
Assert.state(bean != null, "No @Bean annotation attributes"); // Consider name and any aliases
List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
String beanName = (!names.isEmpty() ? names.remove(0) : methodName); // Register aliases even when overridden
for (String alias : names) {
this.registry.registerAlias(beanName, alias);
} // Has this effectively been overridden before (e.g. via XML)?
if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),
beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() +
"' clashes with bean name for containing configuration class; please make those names unique!");
}
return;
} ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
beanDef.setResource(configClass.getResource());
beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource())); if (metadata.isStatic()) {
// static @Bean method
beanDef.setBeanClassName(configClass.getMetadata().getClassName());
beanDef.setFactoryMethodName(methodName);
}
else {
// instance @Bean method
beanDef.setFactoryBeanName(configClass.getBeanName());
beanDef.setUniqueFactoryMethodName(methodName);
}
beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE); 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)) {
beanDef.setInitMethodName(initMethodName);
} String destroyMethodName = bean.getString("destroyMethod");
beanDef.setDestroyMethodName(destroyMethodName); // Consider scoping
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
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));
}
this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}

  ③ 通过@ImportResources导入进来的执行loadBeanDefinitionsFromImportedResources(configClass.getImportedResources())方法:

private void loadBeanDefinitionsFromImportedResources(
Map<String, Class<? extends BeanDefinitionReader>> importedResources) { Map<Class<?>, BeanDefinitionReader> readerInstanceCache = new HashMap<>(); importedResources.forEach((resource, readerClass) -> {
// Default reader selection necessary?
if (BeanDefinitionReader.class == readerClass) {
if (StringUtils.endsWithIgnoreCase(resource, ".groovy")) {
// When clearly asking for Groovy, that's what they'll get...
readerClass = GroovyBeanDefinitionReader.class;
}
else {
// Primarily ".xml" files but for any other extension as well
readerClass = XmlBeanDefinitionReader.class;
}
} 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) {
AbstractBeanDefinitionReader abdr = ((AbstractBeanDefinitionReader) reader);
abdr.setResourceLoader(this.resourceLoader);
abdr.setEnvironment(this.environment);
}
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);
});
}

  ④ 通过ImportBeanDefinition注解导入进来的执行loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars())方法:

private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry));
}

  至此第一步里面的invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry)方法执行完毕!!!!

  下一步:又去容器中获取BeanDefinitionRegistryPostProcessor的bean的处理器名称 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false) 此时就有了自己定义的BeanDefinitionRegistryPostProcessor了,接下来调用自定义的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry后置方法,然后再调用postProcessBeanFactory原因是BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor;

  最后一步:获取容器中所有的BeanFactoryPostProcessor的名称 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false) 此时就有了自己定义的BeanFactoryPostProcessor了,接下来调用自定义的BeanFactoryPostProcessor的postProcessBeanFactory方法;

  完整的Spring IoC源码解析见:Spring系列(三):Spring IoC源码解析

三、Spring IoC扫描Bean的流程图

  总结:通过调用我们的Bean工厂的后置处理器,第一步:ConfigurationClassPostProcessor,解析我们的配置类,将所有的Bean的定义信息注册到Spring IoC容器中;第二步调用自定义的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinition Registry后置方法,然后再调用postProcessBeanFactory;最后调用自定义的BeanFactoryPostProcessor的postProcessBean Factory方法

Spring IoC源码解析之invokeBeanFactoryPostProcessors的更多相关文章

  1. Spring系列(三):Spring IoC源码解析

    一.Spring容器类继承图 二.容器前期准备 IoC源码解析入口: /** * @desc: ioc原理解析 启动 * @author: toby * @date: 2019/7/22 22:20 ...

  2. Spring IoC源码解析之getBean

    一.实例化所有的非懒加载的单实例Bean 从org.springframework.context.support.AbstractApplicationContext#refresh方法开发,进入到 ...

  3. Spring IoC源码解析——Bean的创建和初始化

    Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和AOP的容器框架,主要是针对JavaBean的生命周期进行管理的轻量级容器 ...

  4. Spring IOC 源码解析(持续)

    如何查看源码 Spring源码下载https://github.com/spring-projects/spring-framework/tags?after=v3.1.0.RC1 eclipse关联 ...

  5. spring ioc 源码解析

    什么是ioc? 通俗的解释是:(spring)框架中,完成对象的创建和注入的容器. springIOC体系结构: spring IOC的创建是典型的工厂模式,这一系列的bean工厂如上所示. 其核心是 ...

  6. Spring系列(五):Spring AOP源码解析

    一.@EnableAspectJAutoProxy注解 在主配置类中添加@EnableAspectJAutoProxy注解,开启aop支持,那么@EnableAspectJAutoProxy到底做了什 ...

  7. Spring Boot系列(四):Spring Boot源码解析

    一.自动装配原理 之前博文已经讲过,@SpringBootApplication继承了@EnableAutoConfiguration,该注解导入了AutoConfigurationImport Se ...

  8. spring IoC源码分析 (3)Resource解析

    引自 spring IoC源码分析 (3)Resource解析 定义好了Resource之后,看到XmlFactoryBean的构造函数 public XmlBeanFactory(Resource  ...

  9. Spring IOC 源码分析

    Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器.既然大家平时都要用到 Spring,怎么可以不好好了解 Spring 呢?阅读本文 ...

随机推荐

  1. C++20 的 Modules

    最近看了两篇关于 C++ 20 Modules 很有意思的文章,戳: <Understanding C++ Modules: Part 1: Hello Modules, and Module ...

  2. 学Redis这篇就够了

    Redis 简介 Redis 优势 Redis 数据类型 string hash list set Zset 小总结 基本命令 发布订阅 简介 实例 发布订阅常用命令 事务 实例 Redis 事务命令 ...

  3. pycharm在服务器上远程调试 mac版本

    1. 首先要配置tools 2.点 +,选择SFTP, 填写 New server name:随便填写 3.然后填写 connection 和 Mapping Host:填写远程连接的ip地址 Use ...

  4. 『开发技术』Docker开发教程(一)安装与测试(Windows 家庭版)

    0.前言 针对其他系统和版本,Docker都很容易安装,可以参考官方教程:https://docs.docker.com/docker-hub/ 由于Windows10家庭版无法安装docker,因此 ...

  5. 简单学习之json格式说明

    json格式说明: 1.对象是一个无序的“‘名称/值’对”集合. (1)一个对象以“{”(左括号)开始,“}”(右括号)结束. (2)每个“名称”后跟一个“:”(冒号): (3)“‘名称/值’ 对”之 ...

  6. HBase学习笔记一

    HBase简介 HBase概念 HBase的原型是谷歌的Bigtable论文 HBase是一个高可靠性.高性能.面向列.可伸缩的分布式存储系统,利用HBase技术可在廉价PC上搭建起大规模结构化存储集 ...

  7. DRF + react 实现TodoList

    在web项目构建中有很多框架可供选择,开发人员对项目的使用选择,有很多的影响因素,其中之一就是框架在定义该项目的单独任务时的复杂性. 简介 本文有如下几个部分: 准备 配置后端 配置APIs 配置前端 ...

  8. MyBatis从入门到精通:使用XML方式(映射文件之类的)

    2.3节笔记部分: package tk.mybatis.simple; public class Temp { } /* 2.2 使用XML方式 MyBatis使用了Java的动态代理可以直接通过接 ...

  9. C# ExcelAddIn 开发笔记

    好久都没有写博客了,最近真的是太忙了,接手公司要做的一个小的新的项目,从接触认识到一个新东西,再到自己琢磨研究,最终结合公司业务把整个excel插件项目完成,还是有一点点成就感.以下是项目中基本上大致 ...

  10. pycharm install python packaging tools时遇到AttributeError: '_NamespacePath' object has no attribute 'sort'错误

    pycharm install python packaging tools时报错AttributeError: '_NamespacePath' object has no attribute 's ...