前言
- 上篇博客spring 5.0.x源碼學(xué)習(xí)系列五: AnnotationConfigApplicationContext類refresh方法之invokeBeanFactoryPostProcessor(一)主要解釋的是invokeBeanFactoryPostProcessor方法的大致執(zhí)行流程, 為了精通spring, 咱們除了要了解后置處理器的執(zhí)行順序外案训,還得明白這其中的一個特殊后置處理器(ConfigurationClassPostProcessor)的作用。下面將開始對ConfigurationClassPostProcessor的第一個重要的身份
BeanDefinitionRegistryPostProcessor
進(jìn)行講解(第二個身份BeanFactoryPostProcessor
在下一篇博客進(jìn)行總結(jié))
一专筷、ConfigurationClassPostProcessor之BeanDefinitionRegistryPostProcessor身份
- 它的這個身份起到了非常重要的作用: 處理配置類并解析它們于未。 這句話可能有點(diǎn)難理解, 我們根據(jù)下面的篇幅慢慢理解撕攒。
二、流程圖
-
這里提供一張?zhí)幚砼渲妙惲鞒虉D, 結(jié)合項(xiàng)目demo一起看
三烘浦、項(xiàng)目demo
3.1 項(xiàng)目全景圖
3.1.1 EnableProxy類
3.1.2 ImportEugene類
3.1.3 UserDaoImpl類
3.1.4 ImportEugeneImportSelector類
3.1.5 MyImportBeanDefinitionRegistrar類
3.1.6 ImportEugeneBeanFactoryProcessor類
3.1.7 JDKProxyPostProcessor類
3.1.8 MyInvocationHandler類
3.1.9 ProxyUtil類
3.1.10 UserServiceImpl類
3.1.11 UserService類
3.1.12 AppConfig類
3.1.13 Entry類
3.1.14 TestBeanInAppConfig類
3.1.15 TestDaoInUserDaoImpl類
3.2 demo運(yùn)行結(jié)果
-
AppConfig類
存在
@ImportEugene和 @EnableProxy注解時, 運(yùn)行結(jié)果如下:
=> 打印了7句 ========ImportEugene========的原因是有7個bean要創(chuàng)建, 分別為如下7個bean:AppConfig, UserServiceImpl, UserDaoImpl, ImportEugeneBeanFactoryProcessor, JDKProxyPostProcessor, TestBeanInAppConfig, TestDaoInUserDaoImpl
-
AppConfig類
去除
@ImportEugene和 @EnableProxy注解時, 運(yùn)行結(jié)果如下:
3.4 Demo運(yùn)行結(jié)果總結(jié)
本demo利用了spring的兩個大擴(kuò)展點(diǎn): BeanPostProcessor和 @Import注解抖坪。其中自定義注解 @EnableProxy和 @ImportEugene利用了 @Import注解擴(kuò)展點(diǎn)的兩種類型:
ImportSelector
和ImportBeanDefinitionRegistrar
來實(shí)現(xiàn)-
關(guān)于上述的三個點(diǎn)
BeanPostProcessor
,ImportSelector
,ImportSelector
的功能將以如下表格來闡述擴(kuò)展點(diǎn) 提供api 作用 使用示例 BeanPostProcessor beanName和當(dāng)前bean對象 可以動態(tài)修改bean 本案例中的為UserServiceImpl對象生成代理對象 ImportSelector AnnotationMetadata 能獲取到被導(dǎo)入的那個類的信息, 可以根據(jù)自定義的注解來動態(tài)寫邏輯, 返回的字符串?dāng)?shù)組為類的全類名, spring會把他們當(dāng)成bean去實(shí)例化 本案例中的ImportEugeneBeanFactoryProcessor, 動態(tài)的添加指定bean ImportBeanDefinitionRegistrar AnnotationMetadata和BeanDefinitionRegistry 擁有ImportSelector的api, 同時還能獲取到BeanDefinitionRegister 本案例中的MyImportBeanDefinitionRegistrar, 動態(tài)的添加beanDefinition
四、運(yùn)行原理
4.1 前言
- 本demo中的演示只有幾個部分和ConfigurationClassPostProcessor的BeanDefinitionRegistryPostProcessor身份有關(guān), 只要涉及到bean的創(chuàng)建和bean的執(zhí)行順序, 都不屬于本篇博客的內(nèi)容, 添加一個demo演示是為了更好的說明問題, 現(xiàn)在開始總結(jié)原理
4.2 執(zhí)行原理
4.2.1 在上篇博客中有總結(jié)到invokeBeanFactoryPostProcessors方法執(zhí)行后置處理器的幾個順序闷叉。我們現(xiàn)在將從調(diào)用ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法開始
-
postProcessBeanDefinitionRegistry方法源碼
@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); // 開始處理配置類, registry為bean工廠 processConfigBeanDefinitions(registry); }
-
processConfigBeanDefinitions處理配置類
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { // 存儲配置類的數(shù)據(jù)結(jié)構(gòu): 很重要, 后續(xù)將解析此集合 List<BeanDefinitionHolder> configCandidates = new ArrayList<>(); // 獲取bean工廠的所有beanDefinition的名稱, 在本次demo中, 一共有7個beanDefinition // 為spring內(nèi)置的6個beanDefinition + AppConfig beanDefinition String[] candidateNames = registry.getBeanDefinitionNames(); // 遍歷beanDefinition for (String beanName : candidateNames) { // 根據(jù)beanName到bean工廠中拿到beanDefinition BeanDefinition beanDef = registry.getBeanDefinition(beanName); // 判斷是否為全注解或者部分注解 => 這里正常的spring流程下, 應(yīng)該都沒標(biāo)注 // 除非程序員自己利用擴(kuò)展點(diǎn)修改了配置類對應(yīng)的標(biāo)識 // eg: 標(biāo)識它為全配置類 // 配置類對應(yīng)的beanDefinition.setAttribute( // "org.springframework.context.annotation. // ConfigurationClassPostProcessor.configurationClass", "full"); // eg: 標(biāo)識它為部分配置類 // 配置類對應(yīng)的beanDefinition.setAttribute( // "org.springframework.context.annotation. // ConfigurationClassPostProcessor.configurationClass", "lite"); if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } // 正常情況下會走else, // ConfigurationClassUtils.checkConfigurationClassCandidate的核心邏輯應(yīng)該為如下代碼 // if (isFullConfigurationCandidate(metadata)) { // beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL); // } // else if (isLiteConfigurationCandidate(metadata)) { // beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE); // } // 若當(dāng)前遍歷的beanDefinition是一個配置類或者全配置類則給他一個標(biāo)識, 并返回true // 進(jìn)而將當(dāng)前的beanDefinition添加到configCandidates數(shù)據(jù)結(jié)構(gòu)中 // 這里總結(jié)下什么叫全配置類什么叫部分配置類 // 全配置類: 加了@Configuration注解 // 部分配置類: 類中有@Component擦俐、@Import、@ImportResource握侧、@ComponentScan注解及方法中有@Bean注解的類 else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } // Return immediately if no @Configuration classes were found // 若bean工廠中無配置類, 那么將結(jié)束解析配置類的流程 if (configCandidates.isEmpty()) { return; } // Sort by previously determined @Order value, if applicable configCandidates.sort((bd1, bd2) -> { int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition()); int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition()); return Integer.compare(i1, i2); }); // Detect any custom bean name generation strategy supplied through the enclosing application context // 還未總結(jié)到它的具體作用 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) { this.componentScanBeanNameGenerator = generator; this.importBeanNameGenerator = generator; } } } if (this.environment == null) { this.environment = new StandardEnvironment(); } // Parse each @Configuration class // 生成一個配置類的解析器, 將使用它來對配置類進(jìn)行解析 ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); // 存放在解析配置類過程中得到的新的配置類, eg: 在解析@ComponentScan注解的掃描路徑時, // 有可能掃描到其他的配置類 Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates); // 將register方法中或者使用spring擴(kuò)展點(diǎn)手動添加到bean工廠的配置類添加到存放解析完畢的數(shù)據(jù)結(jié)構(gòu)中, // 為什么這么做蚯瞧? 因?yàn)楹罄m(xù)將挨個去解析candidates的配置類, 并將新掃描出來或者import進(jìn)去的 // 配置類也添加到candidates里面去了, 不需要再解析一遍 Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size()); do { // 解析配置類, 執(zhí)行到此, candidates中只有一個元素, // 因?yàn)樵趫?zhí)行這個步驟的時候只有AppConfig對應(yīng)的beanDefinition在bean工廠中 parser.parse(candidates); parser.validate(); // 拿到配置類解析器得到的配置類 Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses()); // 移出已經(jīng)解析的配置類 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()); } // 加載掃描出來的所有beanDefinition, 并在此將它們挨個注冊到spring bean工廠中 // 所以執(zhí)行到這里時, configClasses中存儲元素內(nèi)容應(yīng)該為: // 根據(jù)candidates中的配置類解析出來的所有配置類 // (包括@Component注解的類、@Import注解導(dǎo)入的普通類品擎、@Configuration的類) this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); candidates.clear(); // 這里還會校驗(yàn)這樣一種情況埋合,因?yàn)樗信渲妙愂谴娴絚andidates變量中 // 而上述this.reader.loadBeanDefinitions(configClasses);代碼 // 只是將配置類中導(dǎo)入的類注冊到bean工廠中去,而此時有可能 // 這些導(dǎo)入的類內(nèi)部也會導(dǎo)入其他的類萄传,所以還需要比較下當(dāng)前解析的配置類 // 中導(dǎo)入的類的數(shù)量和原來獲取的配置類的數(shù)量饥悴。將多出來的配置類數(shù)量進(jìn)行 // 匯總,然后再統(tǒng)一處理它們 if (registry.getBeanDefinitionCount() > candidateNames.length) { String[] newCandidateNames = registry.getBeanDefinitionNames(); Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames)); Set<String> alreadyParsedClasses = new HashSet<>(); for (ConfigurationClass configurationClass : alreadyParsed) { alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); } for (String candidateName : newCandidateNames) { if (!oldCandidateNames.contains(candidateName)) { BeanDefinition bd = registry.getBeanDefinition(candidateName); if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) { candidates.add(new BeanDefinitionHolder(bd, candidateName)); } } } candidateNames = newCandidateNames; } } 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(); } }
-
解析器ConfigurationClassParser之parser方法
public void parse(Set<BeanDefinitionHolder> configCandidates) { this.deferredImportSelectors = new LinkedList<>(); for (BeanDefinitionHolder holder : configCandidates) { BeanDefinition bd = holder.getBeanDefinition(); try { // 這里會根據(jù)當(dāng)前配置類的beanDefinition進(jìn)入不同的解析邏輯, // 通過Register方法注冊的beanDefinition類型統(tǒng)一為AnnotatedBeanDefinition // 這個在之前的博客中有總結(jié)過 if (bd instanceof AnnotatedBeanDefinition) { // 所以解析配置類的時候,是進(jìn)入這個if分支 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(); }
-
解析器ConfigurationClassParser之processConfigurationClass方法 => 會將處理的當(dāng)前配置類存入解析器的configurationClasses集合中
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) { 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 { // 處理完當(dāng)前配置類后, 會在方法中return null => 表示當(dāng)前配置類被解析完成 // 進(jìn)而進(jìn)入下面的邏輯, 將當(dāng)前配置添加到configurationClasses中 // 并在最外部 // org.springframework.context.annotation.ConfigurationClassPostProcessor類 // 中的processConfigBeanDefinitions方法中獲取configurationClasses, 并 // 解析它們(這里的解析不僅僅是注冊beanDefinition, 還包括當(dāng)前配置類中的 // @Bean方法西设、@Import注解導(dǎo)入的類等等) sourceClass = doProcessConfigurationClass(configClass, sourceClass); } while (sourceClass != null); // 上面每次解析完配置類就添加到當(dāng)前對象的configurationClasses屬性中 // 當(dāng)前對象 => 就是在 // org.springframework.context.annotation.ConfigurationClassPostProcessor類中 // 的processConfigBeanDefinitions方法中創(chuàng)建出來的配置類解析器 this.configurationClasses.put(configClass, configClass); }
-
解析器ConfigurationClassParser之doProcessConfigurationClass方法 => 處理@PropertySource, @ComponentScan, @Import, @ImportResource, @Bean注解
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { // Recursively process any member (nested) classes first processMemberClasses(configClass, sourceClass); // 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"); } } // Process any @ComponentScan annotations // 處理@ComponentScan注解, sourceClass為當(dāng)前解析的配置類, 即: AppConfig, 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 // 掃描得到所有擁有@Component注解的beanDefinition, 并在 // 內(nèi)部(this.componentScanParser.parse)將它們注冊到bean工廠 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 for (BeanDefinitionHolder holder : scannedBeanDefinitions) { BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition(); if (bdCand == null) { bdCand = holder.getBeanDefinition(); } // 在此校驗(yàn)掃描出來的@Component注解對應(yīng)的beanDefinition, 因?yàn)橛锌赡芩鼈円脖惶砑恿伺渲妙愊嚓P(guān)的注解, // 所以也把它們當(dāng)做配置類來解析 // 又因?yàn)锧Component注解標(biāo)識的類屬于部分配置類, 所以肯定會將它們當(dāng)做配置類再解析一遍 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { // 這里又調(diào)用了解析配置類邏輯, 遞歸調(diào)用 parse(bdCand.getBeanClassName(), holder.getBeanName()); } } } } // Process any @Import annotations // 處理當(dāng)前配置類的@Import注解 // 該方法的主要邏輯為如下: // 獲取@Import注解的值, 并挨個遍歷它們 /*for (SourceClass candidate : importCandidates) { // 若導(dǎo)入的類是ImportSelector的類型 if (candidate.isAssignable(ImportSelector.class)) { // Candidate class is an ImportSelector -> delegate to it to determine imports Class<?> candidateClass = candidate.loadClass(); // 使用反射創(chuàng)建對象, 為了調(diào)用ImportSelector的方法 ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class); ParserStrategyUtils.invokeAwareMethods( selector, this.environment, this.resourceLoader, this.registry); // 判斷是否為延遲導(dǎo)入, 默認(rèn)為null, 所有走else if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) { this.deferredImportSelectors.add( new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector)); } else { // 調(diào)用ImportSelector的selectImports方法, 得到返回的數(shù)組 String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata()); // 將類對應(yīng)的全路徑轉(zhuǎn)成Collection<SourceClass>類型, 為了下面的遞歸調(diào)用 Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames); // 針對獲取到的類的全路徑, 把它們當(dāng)做Import注解導(dǎo)入的類進(jìn)行處理, 遞歸調(diào)用 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(); // 使用反射創(chuàng)建對象 ImportBeanDefinitionRegistrar registrar = BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class); ParserStrategyUtils.invokeAwareMethods( registrar, this.environment, this.resourceLoader, this.registry); // 將導(dǎo)入的ImportBeanDefinitionRegistrar類型的類添加到當(dāng)前配置類存放ImportBeanDefinitionRegistrar // 類型的集合中, 方便后面處理配置類時能獲取到它們 configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata()); } else { // 非ImportSelector和ImportSelector的selectImports類型的類, 把它當(dāng)成配置類處理 // 在遞歸調(diào)用處理配置類邏輯processConfigurationClass // Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar -> // process it as an @Configuration class this.importStack.registerImport( currentSourceClass.getMetadata(), candidate.getMetadata().getClassName()); processConfigurationClass(candidate.asConfigClass(configClass)); } }*/ processImports(configClass, sourceClass, getImports(sourceClass), true); // Process any @ImportResource annotations // 基于注解的方式的spring, 很少使用此注解, 所以這塊沒有總結(jié)到 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); } } // Process individual @Bean methods // 處理配置類中的方法存在@Bean注解的情況, 挨個遍歷存放到當(dāng)前配置類的數(shù)據(jù)結(jié)構(gòu)中 // 方便在外部處理配置類(loadBeanDefinition)時將它們獲取出來 Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) { configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } // Process default methods on interfaces // 沒總結(jié)到, 暫時忽略 processInterfaces(configClass, sourceClass); // Process superclass, if any // 沒總結(jié)到, 暫時忽略 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(); } } // No superclass -> processing is complete return null; }
-
加載配置類之loadBeanDefinitions方法
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) { TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator(); // 遍歷傳入的配置類集合 for (ConfigurationClass configClass : configurationModel) { loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator); } }
-
加載配置類之loadBeanDefinitionsForConfigurationClass方法
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注解導(dǎo)入的普通類 if (configClass.isImported()) { registerBeanDefinitionForImportedConfigurationClass(configClass); } // 處理當(dāng)前配置類中的所有@Bean標(biāo)識的方法, 并將它注冊到bean工廠 for (BeanMethod beanMethod : configClass.getBeanMethods()) { loadBeanDefinitionsForBeanMethod(beanMethod); } // 加載@ImportedResources注解導(dǎo)入的資源 loadBeanDefinitionsFromImportedResources(configClass.getImportedResources()); // 將@Import注解導(dǎo)入的ImportBeanDefinitionRegistrar類型的bean注冊到bean工廠 loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars()); }
4.2.2 ConfigurationClassPostProcessor做為BeanDefinitionRegistryPostProcessor后置處理器的執(zhí)行結(jié)果
-
執(zhí)行結(jié)果和統(tǒng)計(jì)
BeanDefinition Name | 注冊渠道 |
---|---|
org.springframework.context.annotation.internalConfigurationAnnotationProcessor | AnnotationConfigApplicationContext無參構(gòu)造方法 |
org.springframework.context.event.internalEventListenerFactory | AnnotationConfigApplicationContext無參構(gòu)造方法 |
userServiceImpl | 解析@ComponentScan注解 |
testDaoInUserDaoImpl | @Bean注解 |
testDao | AppConfig類的@Bean注解 |
org.springframework.context.event.internalEventListenerProcessor | AnnotationConfigApplicationContext無參構(gòu)造方法 |
org.springframework.context.annotation.internalAutowiredAnnotationProcessor | AnnotationConfigApplicationContext無參構(gòu)造方法 |
org.springframework.context.annotation.internalCommonAnnotationProcessor | AnnotationConfigApplicationContext無參構(gòu)造方法 |
appConfig | register方法 |
userDaoImpl | 解析@ComponentScan注解 |
JDKProxyPostProcessor | 解析@Import注解 |
org.springframework.context.annotation.internalRequiredAnnotationProcessor | AnnotationConfigApplicationContext無參構(gòu)造方法 |
com.eugene.sumarry.csdn.invokeBeanFactoryPostProcessor2.postprocessor.ImportEugeneBeanFactoryProcessor | 解析@Import注解 |
五瓣铣、小結(jié)
5.1 黑箱理論
- ConfigurationClassPostProcessor之BeanDefinitionRegistryPostProcessor身份的主要作用為:
掃描并解析register方法注冊的配置類, 解析完成后, 所有能被掃描出來的 bean全部都以beanDefinition的形式存在于bean工廠中,為后續(xù)執(zhí)行掃描 出來的后置處理器和創(chuàng)建bean提供了條件
5.2 建議
- 本篇博客提供的大多數(shù)為源碼注釋, 最好是能自己手動搭建與本次demo一樣的項(xiàng)目結(jié)構(gòu), 結(jié)合提供的注釋和運(yùn)行結(jié)果一步一步的去了解ConfigurationClassPostProcessor作為BeanDefinitionRegistryPostProcessor身份的作用
- I am a slow walker, but I never walk backwards.