首页 > 编程语言 >SpringBoot 自动装配源码解析

SpringBoot 自动装配源码解析

时间:2022-11-28 18:22:14浏览次数:43  
标签:SpringBoot imports springframework 源码 org 解析 annotation sourceClass configuratio

SpringBoot 自动装配源码解析

step1:

SpringApplication.run(ZylSpringBootApplication.class,args);

step2:

this.refreshContext(context); -->
org.springframework.boot.SpringApplication#refresh

step3:

this.invokeBeanFactoryPostProcessors(beanFactory); -->
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());

step4:

//org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
//org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
postProcessor.postProcessBeanDefinitionRegistry(registry);
//org.springframework.context.annotation.ConfigurationClassPostProcessor#processConfigBeanDefinitions
this.processConfigBeanDefinitions(registry);

step5:

//org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set<org.springframework.beans.factory.config.BeanDefinitionHolder>)
parser.parse(candidates);
public void parse(Set<BeanDefinitionHolder> configCandidates) {
    Iterator var2 = configCandidates.iterator();

    while(var2.hasNext()) {
        BeanDefinitionHolder holder = (BeanDefinitionHolder)var2.next();
        BeanDefinition bd = holder.getBeanDefinition();

        try {
            if (bd instanceof AnnotatedBeanDefinition) {
                //主程序类从这解析
                this.parse(((AnnotatedBeanDefinition)bd).getMetadata(), holder.getBeanName());
            } else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition)bd).hasBeanClass()) {
                this.parse(((AbstractBeanDefinition)bd).getBeanClass(), holder.getBeanName());
            } else {
                this.parse(bd.getBeanClassName(), holder.getBeanName());
            }
        } catch (BeanDefinitionStoreException var6) {
            throw var6;
        } catch (Throwable var7) {
            throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", var7);
        }
    }

    this.deferredImportSelectorHandler.process();
}

step6:

//org.springframework.context.annotation.ConfigurationClassParser#doProcessConfigurationClass
sourceClass = this.doProcessConfigurationClass(configClass, sourceClass, filter);
this.processImports(configClass, sourceClass, this.getImports(sourceClass), filter, true);
//6.1
private Set<SourceClass> getImports(SourceClass sourceClass) throws IOException {
        Set<SourceClass> imports = new LinkedHashSet();
        Set<SourceClass> visited = new LinkedHashSet();
        this.collectImports(sourceClass, imports, visited);
        return imports;
    }
//6.2 递归收集imports
private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited) throws IOException {
    if (visited.add(sourceClass)) {
        Iterator var4 = sourceClass.getAnnotations().iterator();

        while(var4.hasNext()) {
            SourceClass annotation = (SourceClass)var4.next();
            String annName = annotation.getMetadata().getClassName();
            if (!annName.equals(Import.class.getName())) {
                this.collectImports(annotation, imports, visited);
            }
        }

        imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));
    }
}

image

step7:

this.deferredImportSelectorHandler.process();
handler.processGroupImports();
//org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorGrouping#getImports
grouping.getImports()
//org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup#process    
this.group.process(deferredImport.getConfigurationClass().getMetadata(), deferredImport.getImportSelector());


step8:

AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector)deferredImportSelector).getAutoConfigurationEntry(annotationMetadata);

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

step9:

List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    /*
    protected Class<?> getSpringFactoriesLoaderFactoryClass() {
        return EnableAutoConfiguration.class;
    }
    */
        List<String> configurations = new ArrayList(SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()));
    //老的读EnableAutoConfiguration 
        ImportCandidates.load(AutoConfiguration.class, this.getBeanClassLoader()).forEach(configurations::add);
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories nor in META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }

//新版本从org.springframework.boot.autoconfigure.AutoConfiguration.imports读取
public static ImportCandidates load(Class<?> annotation, ClassLoader classLoader) {
        Assert.notNull(annotation, "'annotation' must not be null");
        ClassLoader classLoaderToUse = decideClassloader(classLoader);
        String location = String.format("META-INF/spring/%s.imports", annotation.getName());
        Enumeration<URL> urls = findUrlsInClasspath(classLoaderToUse, location);
        List<String> autoConfigurations = new ArrayList();

        while(urls.hasMoreElements()) {
            URL url = (URL)urls.nextElement();
            autoConfigurations.addAll(readAutoConfigurations(url));
        }

        return new ImportCandidates(autoConfigurations);
    }

step10:

 // 对configurations进行过滤,剔除掉@Conditional条件不成立的配置类
configurations = this.getConfigurationClassFilter().filter(configurations);
// 把AutoConfigurationImportEvent绑定在所有AutoConfigurationImportListener子类实例上
fireAutoConfigurationImportEvents(configurations, exclusions);
// 返回(configurations, exclusions)组
return new AutoConfigurationEntry(configurations, exclusions);

标签:SpringBoot,imports,springframework,源码,org,解析,annotation,sourceClass,configuratio
From: https://www.cnblogs.com/Acaak/p/16932981.html

相关文章