Spring IoC源码解析之invokeBeanFactoryPostProcessors
- 2019 年 10 月 3 日
- 筆記
一、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方法