Spring 源码详解IOC (一)

   此篇文章将会从启动类开始解析Spring是怎么实现自动装配以及控制反转(基于Spring 5.3.1)
// 启动类调用静态方法run
SpringApplication.run(CodeGenApplication.class, args);
// 继续调用SpringApplication.createApplicationContext创建ApplicationContext以及调用
// AnnotatedBeanDefinitionReader使用AnnotationConfigUtils注册ConfigurationClassPostProcessor  AutowiredAnnotationBeanPostProcessor  CommonAnnotationBeanPostProcessor等后置处理器
// 接下来会调用AbstractApplicationContext.refresh方法
@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

            // Prepare this context for refreshing.
            prepareRefresh();

            // 创建beanFactory以及扫描bean信息然后注册
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 注册了ApplicationContextAwareProcessor 以及其它后置处理器
            // 所有实现了Aware接口的对象在实例化时会调用此AwareProcessor来进行设置对应的属性
            // 如实现了ApplicationContextAware接口的类会在实例化将此时的ApplicationContext设置到该类种
            prepareBeanFactory(beanFactory);

            try {
                // 空方法,交给子类实现
                postProcessBeanFactory(beanFactory);

                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
                // 调用所有 BeanFactoryPostProcessor,此方法会扫描启动类包下的所有Bean对象,
                // 并将满足注入条件的Bean加入到DefaultListableBeanFactory.beanDefinitionMap中此Map为该容器所有bean定义对象集合
                // 调用所有 BeanFactoryPostProcessor,此方法会扫描启动类包下的所有Bean对象并将满足注入条件的Bean(如根注解为@Compontent 包含@Autowire @Repository @Service @Controller等)加入到beanDefinitionMap中也会实例化一部分需要用到的Bean对象
                // 扫描所有第三方依赖的META-INF/spring.factories 使用ConfigurationClassPostProcessor 将spring.factories 中的配置类及其依赖的BeanDefinition注册并实例化
                invokeBeanFactoryPostProcessors(beanFactory);

                // 从beanFactory获取所有实现了BeanPostProcessor的BeanDefinition并实例化然后注册
                registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();

                // 国际化
                initMessageSource();
                initApplicationEventMulticaster();
                onRefresh();
                registerListeners();

                //  17 完成剩下的普通Bean的实例化,前面的步骤注册了大量的BeanDefinition,此时需要进行实例化
                finishBeanFactoryInitialization(beanFactory);

                // Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
                contextRefresh.end();
            }
        }
    }

详解 invokeBeanFactoryPostProcessors(beanFactory)

//以下代码为PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法内代码片段
//由于SpringApplication.createApplicationContext已经注册了实现BeanDefinitionRegistryPostProcessor的ConfigurationClassPostProcessor处理器
//所以此处currentRegistryProcessors包含ConfigurationClassPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//获取优先级最高的Bean定义注册处理器
    if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
        processedBeans.add(ppName);
    }
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 1 执行处理器注册方法,此处执行了ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, 

以下代码为ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry最终执行代码片段,该方法

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    List configCandidates = new ArrayList<>();
    // 2 获取此时BeanFactory的所有Bean定义对象的名字
    String[] candidateNames = registry.getBeanDefinitionNames();

    for (String beanName : candidateNames) {
        BeanDefinition beanDef = 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);
            }
        }
        else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
            // 3 如果该Bean定义信息注解类型包含其中一种@Import @ImportResource @Component @ComponetScan,则加入到configCandidates中,@SpringBootConfiguration根注解为@Component ,所以此处存入的为启动类的Bean定义信息
            configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
        }
    }

    if (configCandidates.isEmpty()) {
        return;
    }

    ConfigurationClassParser parser = new ConfigurationClassParser(
            this.metadataReaderFactory, this.problemReporter, this.environment,
            this.resourceLoader, this.componentScanBeanNameGenerator, registry);

    Set candidates = new LinkedHashSet<>(configCandidates);
    Set alreadyParsed = new HashSet<>(configCandidates.size());
    do {
        StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
        // 4 关键代码
        // 使用ConfigurationClassParser解析启动类
        parser.parse(candidates);
        parser.validate();

        Set configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
        configClasses.removeAll(alreadyParsed);

        if (this.reader == null) {
            this.reader = new ConfigurationClassBeanDefinitionReader(
                    registry, this.sourceExtractor, this.resourceLoader, this.environment,
                    this.importBeanNameGenerator, parser.getImportRegistry());
        }
        this.reader.loadBeanDefinitions(configClasses);

    }
    while (!candidates.isEmpty());

}

public void parse(Set configCandidates) {
    for (BeanDefinitionHolder holder : configCandidates) {
        BeanDefinition bd = holder.getBeanDefinition();
        try {
            if (bd instanceof AnnotatedBeanDefinition) {
                // 5 此处调用下方的doProcessConfigurationClass()
                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);
        }
    }
        //  14 关键切入点 扫描第三方配置以及对应包下可以注入的Bean的定义并注册
        // 第10步已经将AutoConfigurationImportSelector实例化并加入deferredImportSelectorHandler.deferredImportSelectors中,实际会调用AutoConfigurationImportSelector.AutoConfigurationGroup.process()方法
    this.deferredImportSelectorHandler.process();
}

// 6 最后会循环调用
protected final SourceClass doProcessConfigurationClass(
            ConfigurationClass configClass, SourceClass sourceClass, Predicate filter)
            throws IOException {
    // 7 先处理内部类,没有则返回
    if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
        // Recursively process any member (nested) classes first
        processMemberClasses(configClass, sourceClass, filter);
    }

    //  8 处理@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.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
                    "]. Reason: Environment must implement ConfigurableEnvironment");
        }
    }

    // 9 处理 @ComponentScan注解
    Set componentScans = AnnotationConfigUtils.attributesForRepeatable(
            sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
    if (!componentScans.isEmpty() &&
            !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
        for (AnnotationAttributes componentScan : componentScans) {
            // 10 此处会调用ComponentScanAnnotationParser扫描该sourceClass的包下所有满足条件的Bean,并将其BeanDefinition注册到容器中
            Set 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();
                }
                if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
                    parse(bdCand.getBeanClassName(), holder.getBeanName());
                }
            }
        }
    }

    // 11 处理 @Import 注解     getImports(sourceClass)方法会解析sourceClass以及其父注解的@Import  启动类使用@SpringBootApplication父注解为@EnableAutoConfiguration
    //  解析所有@Import内引入的Bean,其中包含AutoConfigurationImportSelector并将其实例化加入到ConfigurationClassParser.deferredImportSelectorHandler.deferredImportSelectors中
    processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

    // 12处理xml配置 @ImportResource 
    AnnotationAttributes importResource =
            AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
    if (importResource != null) {
        String[] resources = importResource.getStringArray("locations");
        Class readerClass = importResource.getClass("reader");
        for (String resource : resources) {
            String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
            configClass.addImportedResource(resolvedResource, readerClass);
        }
    }

    // 13 处理 @Bean 方法 doProcessConfigurationClass结束后返回到parse方法执行第14步(往上看)
    Set beanMethods = retrieveBeanMethodMetadata(sourceClass);
    for (MethodMetadata methodMetadata : beanMethods) {
        configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
    }

    // Process default methods on interfaces
    processInterfaces(configClass, sourceClass);

    // Process superclass, if any
    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;
}

以下代码为AutoConfigurationImportSelector片段

@Override
public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
    Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,
            () -> String.format("Only %s implementations are supported, got %s",
                    AutoConfigurationImportSelector.class.getSimpleName(),
                    deferredImportSelector.getClass().getName()));
    //15 获取配置
    AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
            .getAutoConfigurationEntry(annotationMetadata);
    this.autoConfigurationEntries.add(autoConfigurationEntry);
    for (String importClassName : autoConfigurationEntry.getConfigurations()) {
        this.entries.putIfAbsent(importClassName, annotationMetadata);
    }
}

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    if (!isEnabled(annotationMetadata)) {
        return EMPTY_ENTRY;
    }
    AnnotationAttributes attributes = getAttributes(annotationMetadata);
    List configurations = getCandidateConfigurations(annotationMetadata, attributes);
    configurations = removeDuplicates(configurations);
    Set exclusions = getExclusions(annotationMetadata, attributes);
    checkExcludedClasses(configurations, exclusions);
    configurations.removeAll(exclusions);
    configurations = getConfigurationClassFilter().filter(configurations);
    fireAutoConfigurationImportEvents(configurations, exclusions);
    return new AutoConfigurationEntry(configurations, exclusions);
}

//16 扫描该工程的所有依赖并解析依赖下的META-INF/spring.factories文件,将文件中的配置类读取后返回到调用链
// 根据getCandidateConfigurations返回的配置类的全类名嵌套调用 第6步ConfigurationClassParser.doProcessConfigurationClass
protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    List configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
            getBeanClassLoader());
    Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
            + "are using a custom packaging, make sure that file is correct.");
    return configurations;
}

你可能感兴趣的:(Spring 源码详解IOC (一))