// Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = newArrayList<>();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. // 最后,执行那些不带优先级注解的 BeanDefinitionRegistryPostProcessors 直到不再出现新的 BeanDefinitionRegistryPostProcessor 。为什么会出现呢,因为 BeanDefinitionRegistryPostProcessor 可以注册 BeanDefinitionRegistryPostProcessor 类型的 beanDefinition,所以就要用while循环不停地寻找了。 booleanreiterate=true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); // 出现了新的 BeanDefinitionRegistryPostProcessor, 标记为已执行,并且设置需要继续循环 processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); }
// Now, invoke the postProcessBeanFactory callback of all processors handled so far. // 走到了这里的时候,所有的 BeanDefinitionRegistryPostProcessor 已经调用完其 postProcessBeanDefinitionRegistry() 方法了,这些处理器也都存了下来。由于 BeanDefinitionRegistryPostProcessors 还继承了 BeanFactoryPostProcessor ,因此还需要调用所有 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory() 方法 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); }
else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); }
// Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // 下面的流程比较简单,找出所有的 BeanFactoryPostProcessor ,并按照其优先级依次调用其 postProcessBeanFactory() 方法。 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = newArrayList<>(); List<String> orderedPostProcessorNames = newArrayList<>(); List<String> nonOrderedPostProcessorNames = newArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } elseif (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } elseif (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } }
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = newArrayList<>(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = newArrayList<>(nonOrderedPostProcessorNames.size()); 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(); }
/** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for overriding or adding * properties even to eager-initializing beans. * @param beanFactory the bean factory used by the application context * @throws org.springframework.beans.BeansException in case of errors */ voidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)throws BeansException;
}
/** * Extension to the standard {@link BeanFactoryPostProcessor} SPI, allowing for * the registration of further bean definitions <i>before</i> regular * BeanFactoryPostProcessor detection kicks in. In particular, * BeanDefinitionRegistryPostProcessor may register further bean definitions * which in turn define BeanFactoryPostProcessor instances. * * @author Juergen Hoeller * @since 3.0.1 * @see org.springframework.context.annotation.ConfigurationClassPostProcessor */ publicinterfaceBeanDefinitionRegistryPostProcessorextendsBeanFactoryPostProcessor {
/** * Modify the application context's internal bean definition registry after its * standard initialization. All regular bean definitions will have been loaded, * but no beans will have been instantiated yet. This allows for adding further * bean definitions before the next post-processing phase kicks in. * @param registry the bean definition registry used by the application context * @throws org.springframework.beans.BeansException in case of errors */ voidpostProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)throws BeansException; }
/** * The bean name of the internally managed Configuration annotation processor. */ publicstaticfinalStringCONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME= "org.springframework.context.annotation.internalConfigurationAnnotationProcessor";
/** * The bean name of the internally managed Required annotation processor. * @deprecated as of 5.1, since no Required processor is registered by default anymore */ @Deprecated publicstaticfinalStringREQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME= "org.springframework.context.annotation.internalRequiredAnnotationProcessor";
for (String beanName : candidateNames) { BeanDefinitionbeanDef= registry.getBeanDefinition(beanName); // 这里是判断这bean是否解析过,如果解析过,值会是 lite 或 full if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) { if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } elseif (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(newBeanDefinitionHolder(beanDef, beanName)); } }
// Return immediately if no @Configuration classes were found // 一般到这里,只会有启动类留下来,@SpringBootApplication 包含了 @Configuration if (configCandidates.isEmpty()) { return; }
// Read the model and create bean definitions based on its content if (this.reader == null) { this.reader = newConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses);
candidates.clear(); if (registry.getBeanDefinitionCount() > candidateNames.length) { String[] newCandidateNames = registry.getBeanDefinitionNames(); Set<String> oldCandidateNames = newHashSet<>(Arrays.asList(candidateNames)); Set<String> alreadyParsedClasses = newHashSet<>(); for (ConfigurationClass configurationClass : alreadyParsed) { alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); } for (String candidateName : newCandidateNames) { if (!oldCandidateNames.contains(candidateName)) { BeanDefinitionbd= registry.getBeanDefinition(candidateName); if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) { candidates.add(newBeanDefinitionHolder(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(); } }
// Process default methods on interfaces processInterfaces(configClass, sourceClass);
// Process superclass, if any if (sourceClass.getMetadata().hasSuperClass()) { Stringsuperclass= 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 returnnull; }
publicstaticbooleanisConfigurationCandidate(AnnotationMetadata metadata) { // Do not consider an interface or an annotation... if (metadata.isInterface()) { returnfalse; }
// Any of the typical annotations found? for (String indicator : candidateIndicators) { if (metadata.isAnnotated(indicator)) { returntrue; } }
到此时所有的需要spring托管的类都已经被找到了,我们又该回到之前说的doProcessConfigurationClass方法了,上面所说的都是Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());这一行方法调用的具体内容,现在所有需要托管的类都已经在scannedBeanDefinitions中了,紧接着一次遍历,对每个 bean 进行一次 checkConfigurationClassCandidate调用,用于判断该bean是否是配置类,只要类上面有Component、ComponentScan、Import、ImportResource,或方法上有@Bean,都是配置类,只不过是 lite 模式的配置类,而如果有@Configuration且proxyBeanMethods属性为true的话,会在beanDef中添加 full 属性,其他都添加 lite 属性。
// It's a full or lite configuration candidate... Let's determine the order value, if any. Integerorder= getOrder(metadata); if (order != null) { beanDef.setAttribute(ORDER_ATTRIBUTE, order); }
publicvoidpostProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { intfactoryId= System.identityHashCode(beanFactory); if (this.factoriesPostProcessed.contains(factoryId)) { thrownewIllegalStateException( "postProcessBeanFactory already called on this post-processor against " + beanFactory); } this.factoriesPostProcessed.add(factoryId); if (!this.registriesPostProcessed.contains(factoryId)) { // BeanDefinitionRegistryPostProcessor hook apparently not supported... // Simply call processConfigurationClasses lazily at this point then. processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory); } // 核心代码 enhanceConfigurationClasses(beanFactory); beanFactory.addBeanPostProcessor(newConfigurationClassPostProcessor.ImportAwareBeanPostProcessor(beanFactory)); }
// 对有 Configuration 的类进行增强 publicvoidenhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) { Map<String, AbstractBeanDefinition> configBeanDefs = newLinkedHashMap<>(); for (String beanName : beanFactory.getBeanDefinitionNames()) { BeanDefinitionbeanDef= beanFactory.getBeanDefinition(beanName); ObjectconfigClassAttr= beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE); // ... 此处忽略了一些和主题无关的代码 ... if (ConfigurationClassUtils.CONFIGURATION_CLASS_FULL.equals(configClassAttr)) { if (!(beanDef instanceof AbstractBeanDefinition)) { thrownewBeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" + beanName + "' since it is not stored in an AbstractBeanDefinition subclass"); } elseif (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) { logger.info("Cannot enhance @Configuration bean definition '" + beanName + "' since its singleton instance has been created too early. The typical cause " + "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " + "return type: Consider declaring such methods as 'static'."); } // 如果是 full 模式的配置类,就加在这个 map 里 configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef); } } if (configBeanDefs.isEmpty()) { // nothing to enhance -> return immediately return; }
ConfigurationClassEnhancerenhancer=newConfigurationClassEnhancer(); for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) { AbstractBeanDefinitionbeanDef= entry.getValue(); // If a @Configuration class gets proxied, always proxy the target class beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE); // Set enhanced subclass of the user-specified bean class Class<?> configClass = beanDef.getBeanClass(); // 核心代码,对这个配置类进行增强 Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader); if (configClass != enhancedClass) { if (logger.isTraceEnabled()) { logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " + "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName())); } beanDef.setBeanClass(enhancedClass); } } }
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) { if (EnhancedConfiguration.class.isAssignableFrom(configClass)) { if (logger.isDebugEnabled()) { logger.debug(String.format("Ignoring request to enhance %s as it has " + "already been enhanced. This usually indicates that more than one " + "ConfigurationClassPostProcessor has been registered (e.g. via " + "<context:annotation-config>). This is harmless, but you may " + "want check your configuration and remove one CCPP if possible", configClass.getName())); } return configClass; } Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader)); if (logger.isTraceEnabled()) { logger.trace(String.format("Successfully enhanced %s; enhanced class name is: %s", configClass.getName(), enhancedClass.getName())); } return enhancedClass; }
private static final Callback[] CALLBACKS = new Callback[] { new BeanMethodInterceptor(), new BeanFactoryAwareMethodInterceptor(), NoOp.INSTANCE };
private Class<?> createClass(Enhancer enhancer) { Class<?> subclass = enhancer.createClass(); // Registering callbacks statically (as opposed to thread-local) // is critical for usage in an OSGi environment (SPR-5932)... Enhancer.registerStaticCallbacks(subclass, CALLBACKS); return subclass; }
// Determine whether this bean is a scoped-proxy if (BeanAnnotationHelper.isScopedProxy(beanMethod)) { StringscopedBeanName= ScopedProxyCreator.getTargetBeanName(beanName); if (beanFactory.isCurrentlyInCreation(scopedBeanName)) { beanName = scopedBeanName; } } // ...省去了一些和主题无关的代码...
// 判断当前被拦截的方法是当前方法,还是被其它方法调用的,如果是被其它方法调用的会返回false if (isCurrentlyInvokedFactoryMethod(beanMethod)) { // The factory is calling the bean method in order to instantiate and register the bean // (i.e. via a getBean() call) -> invoke the super implementation of the method to actually // create the bean instance. if (logger.isInfoEnabled() && BeanFactoryPostProcessor.class.isAssignableFrom(beanMethod.getReturnType())) { logger.info(String.format("@Bean method %s.%s is non-static and returns an object " + "assignable to Spring's BeanFactoryPostProcessor interface. This will " + "result in a failure to process annotations such as @Autowired, " + "@Resource and @PostConstruct within the method's declaring " + "@Configuration class. Add the 'static' modifier to this method to avoid " + "these container lifecycle issues; see @Bean javadoc for complete details.", beanMethod.getDeclaringClass().getSimpleName(), beanMethod.getName())); } // 如果当前方法就是被拦截的方法,那直接走代理,执行原方法就行了。 return cglibMethodProxy.invokeSuper(enhancedConfigInstance, beanMethodArgs); } // 如果拦截的方法不是当前方法,是方法调用,那就尝试去获取这个bean,如果没有的话就会去创建bean。 return resolveBeanReference(beanMethod, beanMethodArgs, beanFactory, beanName); }