通过红黑树的定义,可确保其没有一条路径长度能够超出其他路径的2倍。 通过下图可知,因为需要保证从根到每个叶节点的黑色节点数量(黑色高度)相等,所以左侧为black -> red -> black -> red -> black -> null 右侧为black -> black -> black -> null从根节点到NIL节点(图中标为NULL)都只有三个,两者高度相差相差是小于2倍的。
// WARNING: Although it may appear that the body of this method can be easily // refactored to avoid the use of multiple loops and multiple lists, the use // of multiple lists and multiple passes over the names of processors is // intentional. We must ensure that we honor the contracts for PriorityOrdered // and Ordered processors. Specifically, we must NOT cause processors to be // instantiated (via getBean() invocations) or registered in the ApplicationContext // in the wrong order. // // Before submitting a pull request (PR) to change this method, please review the // list of all declined PRs involving changes to PostProcessorRegistrationDelegate // to ensure that your proposal does not result in a breaking change: // https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
// Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = newHashSet<>();
// 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, for example, replacing placeholders in values... beanFactory.clearMetadataCache(); }
Spring 在 invokeBeanFactoryPostProcessors() 时执行所有 BeanFactoryPostProcessor,其中 ConfigurationClassPostProcessor 是 Spring 内置的 BeanFactoryPostProcessor,优先执行。
@Override publicvoidpostProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { intregistryId= System.identityHashCode(registry); if (this.registriesPostProcessed.contains(registryId)) { thrownewIllegalStateException( "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry); } if (this.factoriesPostProcessed.contains(registryId)) { thrownewIllegalStateException( "postProcessBeanFactory already called on this post-processor against " + registry); } this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry); }
publicvoidprocessConfigBeanDefinitions(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = newArrayList<>(); // 获取所有注册的bean类型 String[] candidateNames = registry.getBeanDefinitionNames(); //遍历所有的bean类,寻找有@Configuration注解的类 for (String beanName : candidateNames) { BeanDefinitionbeanDef= registry.getBeanDefinition(beanName); if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) { if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } // 如果bean类中包含@Configuration注解则将该类加入到configCandidates List中 elseif (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(newBeanDefinitionHolder(beanDef, beanName)); } }
// Return immediately if no @Configuration classes were found 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); processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
candidates.clear(); if (registry.getBeanDefinitionCount() > candidateNames.length) { String[] newCandidateNames = registry.getBeanDefinitionNames(); Set<String> oldCandidateNames = Set.of(candidateNames); Set<String> alreadyParsedClasses = CollectionUtils.newHashSet(alreadyParsed.size()); 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 (singletonRegistry != null && !singletonRegistry.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) { singletonRegistry.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); }
// Store the PropertySourceDescriptors to contribute them Ahead-of-time if necessary this.propertySourceDescriptors = parser.getPropertySourceDescriptors();
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory 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.clearCache(); } }
开发模式:classpath 包含了target/classes/(编译前来自于src/main/resources/)和Maven从本地仓库中获取的依赖包(~/.m2/repository/xxx.jar)。此模式下Maven会解析pom.xml,并自动添加~/.m2/repository/ 里的 JAR 到 classpath
Spring Boot Fat JAR 模式:此时SpringBoot不使用classpath,而是用 LaunchedURLClassLoader 来解析 BOOT-INF/lib/ 里的 JAR。此模式下Maven会将依赖包从~/.m2/repository/中直接复制到target/myapp-1.0.0.jar/BOOT-INF/lib/中。
// Prepare this context for refreshing. // 检查SpringBoot中的环境变量 prepareRefresh();
// Tell the subclass to refresh the internal bean factory. // 从子类中获取beanfactory,默认是ConfigurableListableBeanFactory ConfigurableListableBeanFactorybeanFactory= obtainFreshBeanFactory();
// Prepare the bean factory for use in this context. //为 ConfigurableListableBeanFactory配置一些基础设置和功能,以确保它能够正确地创建和管理 Bean prepareBeanFactory(beanFactory);
try { // Allows post-processing of the bean factory in context subclasses. // 允许子类对beanFactory中的bean在初始化之前修改bean postProcessBeanFactory(beanFactory);
StartupStepbeanPostProcess=this.applicationStartup.start("spring.context.beans.post-process"); // Invoke factory processors registered as beans in the context. // 处理注解的主要方法 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 注册BeanPostProcessors的bean类 registerBeanPostProcessors(beanFactory); beanPostProcess.end();
// Initialize message source for this context. // 添加消息bean initMessageSource();
// Initialize event multicaster for this context. // 添加事件传播bean initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses. // 处理子类的刷新,如Servlet的启动Tomcat onRefresh();
// Check for listener beans and register them. // 注册监听bean registerListeners();
// BeanFactory interface not registered as resolvable type in a plain factory. // MessageSource registered (and found for autowiring) as a bean. // 为一些常见的类型注册默认的单例 Bean, 可以通过依赖注入直接获取对应的实例 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(newApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found. if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); }
// Register default environment beans. if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) { beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup()); } }
// WARNING: Although it may appear that the body of this method can be easily // refactored to avoid the use of multiple loops and multiple lists, the use // of multiple lists and multiple passes over the names of processors is // intentional. We must ensure that we honor the contracts for PriorityOrdered // and Ordered processors. Specifically, we must NOT cause processors to be // instantiated (via getBean() invocations) or registered in the ApplicationContext // in the wrong order. // // Before submitting a pull request (PR) to change this method, please review the // list of all declined PRs involving changes to PostProcessorRegistrationDelegate // to ensure that your proposal does not result in a breaking change: // https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
// Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = newHashSet<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor registryProcessor) { registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } }
// 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<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. 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)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); currentRegistryProcessors.clear(); }
// Now, invoke the postProcessBeanFactory callback of all processors handled so far. 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! 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, for example, replacing placeholders in values... beanFactory.clearMetadataCache(); }