1.核心:

SpringApplication.run(SpringbootdemoApplication.class, args);

内部

2.初始化:

new SpringApplication(primarySources)

其中重要的:

this.webApplicationType = this.deduceWebApplicationType();//根据是否存在"javax.servlet.Servlet", "org.springframework.web.context.ConfigurableWebApplicationContext"返回类型,这里返回WebApplicationType.SERVLET
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));//设置初始化工厂类this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));//设置初始化监听this.mainApplicationClass = this.deduceMainApplicationClass();//设置含"main"的主类

其中

this.getSpringFactoriesInstances

方法从classpath的所有

"META-INF/spring.factories"

中加载方法参数对应的类(一个集合),返回其中每个类的实例的集合,这里

工厂类集合:

# Application Context Initializersorg.springframework.context.ApplicationContextInitializer=\org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\org.springframework.boot.context.ContextIdApplicationContextInitializer,\org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

监听集合:

# Application Listenersorg.springframework.context.ApplicationListener=\org.springframework.boot.ClearCachesApplicationListener,\org.springframework.boot.builder.ParentContextCloserApplicationListener,\org.springframework.boot.context.FileEncodingApplicationListener,\org.springframework.boot.context.config.AnsiOutputApplicationListener,\org.springframework.boot.context.config.ConfigFileApplicationListener,\org.springframework.boot.context.config.DelegatingApplicationListener,\org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\org.springframework.boot.context.logging.LoggingApplicationListener,\org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

3.run方法:

(new SpringApplication(primarySources)).run(args)

其中重要的:

SpringApplicationRunListeners listeners = this.getRunListeners(args);

内部同样调用上面的

this.getSpringFactoriesInstances

方法加载并实例化

EventPublishingRunListener

使用其

EventPublishingRunListener(SpringApplication application, String[] args)

构造方法,第一个参数传递的是上面初始化好的SpringApplication,第二个参数是启动类传递的命令行参数数组

然后

listeners.starting();

将每个监听开启。

4.run方法中的Spring容器初始化部分

context = this.createApplicationContext();

方法,根据

this.webApplicationType

加载、实例化不同的BeanFactory实例,这里实例化

org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext

这个实例化当中,AnnotationConfigServletWebServerApplicationContext最终继承GenericApplicationContext,该父类构造方法中:

public GenericApplicationContext() {    this.customClassLoader = false;    this.refreshed = new AtomicBoolean();    this.beanFactory = new DefaultListableBeanFactory();}

实例化了一个DefaultListableBeanFactory,它是Spring和核心BeanFactory类,将完成下面重要的Spring容器初始化过程。

但这里的Spring初始化入口是AnnotationConfigServletWebServerApplicationContext自己的构造方法:

public AnnotationConfigServletWebServerApplicationContext() {    this.annotatedClasses = new LinkedHashSet();    this.reader = new AnnotatedBeanDefinitionReader(this);    this.scanner = new ClassPathBeanDefinitionScanner(this);}

加粗方法内部,执行的是AnnotatedBeanDefinitionReader类的构造方法:

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {    this.beanNameGenerator = new AnnotationBeanNameGenerator();    this.scopeMetadataResolver = new AnnotationScopeMetadataResolver();    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");    Assert.notNull(environment, "Environment must not be null");    this.registry = registry;    this.conditionEvaluator = new ConditionEvaluator(registry, environment, (ResourceLoader)null);    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}

这里的BeanDefinitionRegistry就是实例化AnnotatedBeanDefinitionReader时传入的AnnotationConfigServletWebServerApplicationContext实例,它最终(通过GenericApplicationContext)实现了BeanDefinitionRegistry.

加粗方法进入AnnotationConfigUtils的registerAnnotationConfigProcessors方法:

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);    if (beanFactory != null) {        if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {            beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);        }

        if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {            beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());        }    }

    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet(8);    RootBeanDefinition def;    if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) {def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);        def.setSource(source);        beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"));    }

    if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) {        def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);        def.setSource(source);        beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor"));    }

    if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalRequiredAnnotationProcessor")) {        def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);        def.setSource(source);        beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalRequiredAnnotationProcessor"));    }

    if (jsr250Present && !registry.containsBeanDefinition("org.springframework.context.annotation.internalCommonAnnotationProcessor")) {        def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);        def.setSource(source);        beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalCommonAnnotationProcessor"));    }

    if (jpaPresent && !registry.containsBeanDefinition("org.springframework.context.annotation.internalPersistenceAnnotationProcessor")) {        def = new RootBeanDefinition();

        try {            def.setBeanClass(ClassUtils.forName("org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", AnnotationConfigUtils.class.getClassLoader()));        } catch (ClassNotFoundException var6) {            throw new IllegalStateException("Cannot load optional framework class: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", var6);        }

        def.setSource(source);        beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalPersistenceAnnotationProcessor"));    }

    if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerProcessor")) {        def = new RootBeanDefinition(EventListenerMethodProcessor.class);        def.setSource(source);        beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerProcessor"));    }

    if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerFactory")) {        def = new RootBeanDefinition(DefaultEventListenerFactory.class);        def.setSource(source);        beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerFactory"));    }

    return beanDefs;}

该方法创建了后处理器Bean的BeanDefinition,并使用BeanDefinitionRegistry注册了一些后处理器,比如:

registerPostProcessor(registry, def, "org.springframework.context.annotation.internalRequiredAnnotationProcessor")

在这个registerPostProcessor方法中:

private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {    definition.setRole(2);    registry.registerBeanDefinition(beanName, definition);    return new BeanDefinitionHolder(definition, beanName);}

加粗方法最终进入GenericApplicationContext中实例化的DefaultListableBeanFactory进行BeanDefinition的注册,这里是注册后处理器Bean,以下就是DefaultListableBeanFactory中重要的BeanDefinition注册方法:

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {    Assert.hasText(beanName, "Bean name must not be empty");    Assert.notNull(beanDefinition, "BeanDefinition must not be null");    if (beanDefinition instanceof AbstractBeanDefinition) {        try {            ((AbstractBeanDefinition)beanDefinition).validate();        } catch (BeanDefinitionValidationException var9) {            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9);        }    }

    BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);    if (existingDefinition != null) {        if (!this.isAllowBeanDefinitionOverriding()) {            throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + existingDefinition + "] bound.");        }

        if (existingDefinition.getRole() < beanDefinition.getRole()) {            if (this.logger.isWarnEnabled()) {                this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");            }        } else if (!beanDefinition.equals(existingDefinition)) {            if (this.logger.isInfoEnabled()) {                this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");            }        } else if (this.logger.isDebugEnabled()) {            this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");        }

        this.beanDefinitionMap.put(beanName, beanDefinition);    } else {        if (this.hasBeanCreationStarted()) {            Map var4 = this.beanDefinitionMap;            synchronized(this.beanDefinitionMap) {                this.beanDefinitionMap.put(beanName, beanDefinition);                List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);                updatedDefinitions.addAll(this.beanDefinitionNames);                updatedDefinitions.add(beanName);                this.beanDefinitionNames = updatedDefinitions;                if (this.manualSingletonNames.contains(beanName)) {                    Set<String> updatedSingletons = new LinkedHashSet(this.manualSingletonNames);                    updatedSingletons.remove(beanName);                    this.manualSingletonNames = updatedSingletons;                }            }        } else {this.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName);            this.manualSingletonNames.remove(beanName);        }

        this.frozenBeanDefinitionNames = null;    }

    if (existingDefinition != null || this.containsSingleton(beanName)) {        this.resetBeanDefinition(beanName);    }

}

该方法最终在beanDefinitionMap中存储了7个后处理器:

这里的context就是创建的AnnotationConfigServletWebServerApplicationContext,内部的BeanFactory就是其内部实例化的DefaultListableBeanFactory,beanDefinitionMap就在它内部。

这个方法在后面我们自定义Bean的注册中会反复使用。

5.下一个重要方法:

this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);

该方法:

private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {    context.setEnvironment(environment);    this.postProcessApplicationContext(context);    this.applyInitializers(context);    listeners.contextPrepared(context);    if (this.logStartupInfo) {        this.logStartupInfo(context.getParent() == null);        this.logStartupProfileInfo(context);    }

    context.getBeanFactory().registerSingleton("springApplicationArguments", applicationArguments);    if (printedBanner != null) {        context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);    }

Set<Object> sources = this.getAllSources();    Assert.notEmpty(sources, "Sources must not be empty");this.load(context, sources.toArray(new Object[0]));    listeners.contextLoaded(context);}

中,sources代表初始化资源,这里是SpringApplication实例化时传入的主类SpringbootdemoApplication,然后带着资源进入load方法:

protected void load(ApplicationContext context, Object[] sources) {    if (logger.isDebugEnabled()) {        logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));    }

BeanDefinitionLoader loader = this.createBeanDefinitionLoader(this.getBeanDefinitionRegistry(context), sources);    if (this.beanNameGenerator != null) {        loader.setBeanNameGenerator(this.beanNameGenerator);    }

    if (this.resourceLoader != null) {        loader.setResourceLoader(this.resourceLoader);    }

    if (this.environment != null) {        loader.setEnvironment(this.environment);    }

loader.load();}

第一个加粗方法使用AnnotationConfigServletWebServerApplicationContext(实现了BeanDefinitionRegistry)和资源创建一个BeanDefinitionLoader:

BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) {    Assert.notNull(registry, "Registry must not be null");    Assert.notEmpty(sources, "Sources must not be empty");    this.sources = sources;this.annotatedReader = new AnnotatedBeanDefinitionReader(registry);    this.xmlReader = new XmlBeanDefinitionReader(registry);    if (this.isGroovyPresent()) {        this.groovyReader = new GroovyBeanDefinitionReader(registry);    }

this.scanner = new ClassPathBeanDefinitionScanner(registry);    this.scanner.addExcludeFilter(new BeanDefinitionLoader.ClassExcludeFilter(sources));}

第一句加粗和上面一样,使用registry创建了一个AnnotatedBeanDefinitionReader,内部还是DefaultListableBeanFactory的那7个后处理器

第二句加粗,创建了

出了BeanDefinitionLoader的整个创建后,接着上面SpringApplication的load方法,使用刚刚创建的BeanDefinitionLoader的load方法,该方法最终调用其重载方法:

private int load(Class<?> source) {    if (this.isGroovyPresent() && BeanDefinitionLoader.GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {        BeanDefinitionLoader.GroovyBeanDefinitionSource loader = (BeanDefinitionLoader.GroovyBeanDefinitionSource)BeanUtils.instantiateClass(source, BeanDefinitionLoader.GroovyBeanDefinitionSource.class);        this.load(loader);    }

    if (this.isComponent(source)) {this.annotatedReader.register(new Class[]{source});        return 1;    } else {        return 0;    }}

其中的资源就是主类SpringbootdemoApplication,这个方法最终进入AnnotatedBeanDefinitionReader的方法:

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);    if (!this.conditionEvaluator.shouldSkip(abd.getMetadata())) {        abd.setInstanceSupplier(instanceSupplier);        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);        abd.setScope(scopeMetadata.getScopeName());        String beanName = name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry);        AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);        int var10;        int var11;        if (qualifiers != null) {            Class[] var9 = qualifiers;            var10 = qualifiers.length;

            for(var11 = 0; var11 < var10; ++var11) {                Class<? extends Annotation> qualifier = var9[var11];                if (Primary.class == qualifier) {                    abd.setPrimary(true);                } else if (Lazy.class == qualifier) {                    abd.setLazyInit(true);                } else {                    abd.addQualifier(new AutowireCandidateQualifier(qualifier));                }            }        }

        BeanDefinitionCustomizer[] var13 = definitionCustomizers;        var10 = definitionCustomizers.length;

        for(var11 = 0; var11 < var10; ++var11) {            BeanDefinitionCustomizer customizer = var13[var11];            customizer.customize(abd);        }

BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);    }}

这里的最后,将主类处理成BeanDefinitionHolder,和registry一起传入,进入BeanDefinitionReaderUtils:

public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {    String beanName = definitionHolder.getBeanName();registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());    String[] aliases = definitionHolder.getAliases();    if (aliases != null) {        String[] var4 = aliases;        int var5 = aliases.length;

        for(int var6 = 0; var6 < var5; ++var6) {            String alias = var4[var6];            registry.registerAlias(beanName, alias);        }    }

}

加粗一句和上面的分析是一样的,最终使用将主类实例注册到DefaultListableBeanFactory的beanDefinitionMap中。

6.下一个重要的方法:

this.refreshContext(context);

最终将我们的AnnotationConfigServletWebServerApplicationContext强转成底层基类

AbstractApplicationContext

调用其refresh方法:

public void refresh() throws BeansException, IllegalStateException {    Object var1 = this.startupShutdownMonitor;    synchronized(this.startupShutdownMonitor) {        this.prepareRefresh();ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();        this.prepareBeanFactory(beanFactory);

        try {            this.postProcessBeanFactory(beanFactory);this.invokeBeanFactoryPostProcessors(beanFactory);            this.registerBeanPostProcessors(beanFactory);            this.initMessageSource();            this.initApplicationEventMulticaster();            this.onRefresh();            this.registerListeners();            this.finishBeanFactoryInitialization(beanFactory);            this.finishRefresh();        } catch (BeansException var9) {            if (this.logger.isWarnEnabled()) {                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);            }

            this.destroyBeans();            this.cancelRefresh(var9);            throw var9;        } finally {            this.resetCommonCaches();        }

    }}

这里的beanFactory仍然是AnnotationConfigServletWebServerApplicationContext内部创建的DefaultListableBeanFactory,且当前一共有包括主类和后处理器在内的8个BeanDefinition.这里进入invokeBeanFactoryPostProcessors方法,该方法最终进入PostProcessorRegistrationDelegate类的静态方法:

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {    Set<String> processedBeans = new HashSet();    ArrayList regularPostProcessors;    ArrayList registryProcessors;    int var9;    ArrayList currentRegistryProcessors;    String[] postProcessorNames;    if (beanFactory instanceof BeanDefinitionRegistry) {        BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;        regularPostProcessors = new ArrayList();        registryProcessors = new ArrayList();        Iterator var6 = beanFactoryPostProcessors.iterator();

        while(var6.hasNext()) {            BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {                BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;                registryProcessor.postProcessBeanDefinitionRegistry(registry);                registryProcessors.add(registryProcessor);            } else {                regularPostProcessors.add(postProcessor);            }        }

        currentRegistryProcessors = new ArrayList();        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);        String[] var16 = postProcessorNames;        var9 = postProcessorNames.length;

        int var10;        String ppName;        for(var10 = 0; var10 < var9; ++var10) {            ppName = var16[var10];            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);        currentRegistryProcessors.clear();        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);        var16 = postProcessorNames;        var9 = postProcessorNames.length;

        for(var10 = 0; var10 < var9; ++var10) {            ppName = var16[var10];            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);        currentRegistryProcessors.clear();        boolean reiterate = true;

        while(reiterate) {            reiterate = false;            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);            String[] var19 = postProcessorNames;            var10 = postProcessorNames.length;

            for(int var26 = 0; var26 < var10; ++var26) {                String ppName = var19[var26];                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);            currentRegistryProcessors.clear();        }

        invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);        invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);    } else {        invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);    }

    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);    regularPostProcessors = new ArrayList();    registryProcessors = new ArrayList();    currentRegistryProcessors = new ArrayList();    postProcessorNames = postProcessorNames;    int var20 = postProcessorNames.length;

    String ppName;    for(var9 = 0; var9 < var20; ++var9) {        ppName = postProcessorNames[var9];        if (!processedBeans.contains(ppName)) {            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {                regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));            } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {                registryProcessors.add(ppName);            } else {                currentRegistryProcessors.add(ppName);            }        }    }

    sortPostProcessors(regularPostProcessors, beanFactory);    invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList();    Iterator var21 = registryProcessors.iterator();

    while(var21.hasNext()) {        String postProcessorName = (String)var21.next();        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));    }

    sortPostProcessors(orderedPostProcessors, beanFactory);    invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList();    Iterator var24 = currentRegistryProcessors.iterator();

    while(var24.hasNext()) {        ppName = (String)var24.next();        nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));    }

    invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);    beanFactory.clearMetadataCache();}

该方法传入三个后处理器,重要的一个是ConfigurationClassPostProcessor,用来解析主类,将其所在包内所有类的注解配置解析,创建、注册需要的Bean,这里执行加粗方法:

private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {    Iterator var2 = postProcessors.iterator();

    while(var2.hasNext()) {        BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor)var2.next();postProcessor.postProcessBeanDefinitionRegistry(registry);    }

}

上面加粗方法,其中的ConfigurationClassPostProcessor执行的是其下面的方法:

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {    List<BeanDefinitionHolder> configCandidates = new ArrayList();String[] candidateNames = registry.getBeanDefinitionNames();    String[] var4 = candidateNames;    int var5 = candidateNames.length;

    for(int var6 = 0; var6 < var5; ++var6) {        String beanName = var4[var6];BeanDefinition beanDef = registry.getBeanDefinition(beanName);        if (!ConfigurationClassUtils.isFullConfigurationClass(beanDef) && !ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {            if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));            }        } else if (this.logger.isDebugEnabled()) {            this.logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);        }    }

    if (!configCandidates.isEmpty()) {        configCandidates.sort((bd1, bd2) -> {            int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());            int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());            return Integer.compare(i1, i2);        });        SingletonBeanRegistry sbr = null;        if (registry instanceof SingletonBeanRegistry) {sbr = (SingletonBeanRegistry)registry;            if (!this.localBeanNameGeneratorSet) {BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator");                if (generator != null) {this.componentScanBeanNameGenerator = generator;                    this.importBeanNameGenerator = generator;                }            }        }

        if (this.environment == null) {            this.environment = new StandardEnvironment();        }

ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);        Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates);        HashSet alreadyParsed = new HashSet(configCandidates.size());

        do {parser.parse(candidates);            parser.validate();            Set<ConfigurationClass> 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);            alreadyParsed.addAll(configClasses);            candidates.clear();            if (registry.getBeanDefinitionCount() > candidateNames.length) {                String[] newCandidateNames = registry.getBeanDefinitionNames();                Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames));                Set<String> alreadyParsedClasses = new HashSet();                Iterator var12 = alreadyParsed.iterator();

                while(var12.hasNext()) {                    ConfigurationClass configurationClass = (ConfigurationClass)var12.next();                    alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());                }

                String[] var23 = newCandidateNames;                int var24 = newCandidateNames.length;

                for(int var14 = 0; var14 < var24; ++var14) {                    String candidateName = var23[var14];                    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());

        if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {            sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());        }

        if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {            ((CachingMetadataReaderFactory)this.metadataReaderFactory).clearCache();        }

    }}

上面的

parser.parse(candidates);

ConfigurationClassParser的方法,

进入其

@Nullableprotected final ConfigurationClassParser.SourceClass doProcessConfigurationClass(ConfigurationClass configClass, ConfigurationClassParser.SourceClass sourceClass) throws IOException {    this.processMemberClasses(configClass, sourceClass);    Iterator var3 = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class, PropertySource.class).iterator();

    AnnotationAttributes importResource;    while(var3.hasNext()) {        importResource = (AnnotationAttributes)var3.next();        if (this.environment instanceof ConfigurableEnvironment) {            this.processPropertySource(importResource);        } else {            this.logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment");        }    }

    Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);    if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {        Iterator var13 = componentScans.iterator();

        while(var13.hasNext()) {            AnnotationAttributes componentScan = (AnnotationAttributes)var13.next();Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());            Iterator var7 = scannedBeanDefinitions.iterator();

            while(var7.hasNext()) {                BeanDefinitionHolder holder = (BeanDefinitionHolder)var7.next();                BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();                if (bdCand == null) {                    bdCand = holder.getBeanDefinition();                }

                if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {                    this.parse(bdCand.getBeanClassName(), holder.getBeanName());                }            }        }    }

    this.processImports(configClass, sourceClass, this.getImports(sourceClass), true);    importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);    if (importResource != null) {        String[] resources = importResource.getStringArray("locations");        Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");        String[] var19 = resources;        int var21 = resources.length;

        for(int var22 = 0; var22 < var21; ++var22) {            String resource = var19[var22];            String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);            configClass.addImportedResource(resolvedResource, readerClass);        }    }

    Set<MethodMetadata> beanMethods = this.retrieveBeanMethodMetadata(sourceClass);    Iterator var17 = beanMethods.iterator();

    while(var17.hasNext()) {        MethodMetadata methodMetadata = (MethodMetadata)var17.next();        configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));    }

    this.processInterfaces(configClass, sourceClass);    if (sourceClass.getMetadata().hasSuperClass()) {        String superclass = sourceClass.getMetadata().getSuperClassName();        if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {            this.knownSuperclasses.put(superclass, configClass);            return sourceClass.getSuperClass();        }    }

    return null;}

方法,加粗方法进入ComponentScanAnnotationParser的parse方法,该方法创建了ClassPathBeanDefinitionScanner实例,进入其doScan方法:

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {    Assert.notEmpty(basePackages, "At least one base package must be specified");    Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet();    String[] var3 = basePackages;    int var4 = basePackages.length;

    for(int var5 = 0; var5 < var4; ++var5) {        String basePackage = var3[var5];        Set<BeanDefinition> candidates = this.findCandidateComponents(basePackage);        Iterator var8 = candidates.iterator();

        while(var8.hasNext()) {            BeanDefinition candidate = (BeanDefinition)var8.next();            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);            candidate.setScope(scopeMetadata.getScopeName());            String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);            if (candidate instanceof AbstractBeanDefinition) {                this.postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName);            }

            if (candidate instanceof AnnotatedBeanDefinition) {                AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate);            }

            if (this.checkCandidate(beanName, candidate)) {                BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);                definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);                beanDefinitions.add(definitionHolder);                this.registerBeanDefinition(definitionHolder, this.registry);            }        }    }

    return beanDefinitions;}

这里的basePackages是上层解析主类解析出来的该类包名,这个方法内部又经过ClassPathScanningCandidateComponentProvider的scanCandidateComponents方法:

private Set<BeanDefinition> scanCandidateComponents(String basePackage) {    LinkedHashSet candidates = new LinkedHashSet();

    try {String packageSearchPath = "classpath*:" + this.resolveBasePackage(basePackage) + '/' + this.resourcePattern;        Resource[] resources = this.getResourcePatternResolver().getResources(packageSearchPath);        boolean traceEnabled = this.logger.isTraceEnabled();        boolean debugEnabled = this.logger.isDebugEnabled();Resource[] var7 = resources;        int var8 = resources.length;

        for(int var9 = 0; var9 < var8; ++var9) {Resource resource = var7[var9];            if (traceEnabled) {                this.logger.trace("Scanning " + resource);            }

            if (resource.isReadable()) {                try {                    MetadataReader metadataReader = this.getMetadataReaderFactory().getMetadataReader(resource);                    if (this.isCandidateComponent(metadataReader)) {ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);                        sbd.setResource(resource);                        sbd.setSource(resource);                        if (this.isCandidateComponent((AnnotatedBeanDefinition)sbd)) {                            if (debugEnabled) {                                this.logger.debug("Identified candidate component class: " + resource);                            }

candidates.add(sbd);                        } else if (debugEnabled) {                            this.logger.debug("Ignored because not a concrete top-level class: " + resource);                        }                    } else if (traceEnabled) {                        this.logger.trace("Ignored because not matching any filter: " + resource);                    }                } catch (Throwable var13) {                    throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, var13);                }            } else if (traceEnabled) {                this.logger.trace("Ignored because not readable: " + resource);            }        }

return candidates;    } catch (IOException var14) {        throw new BeanDefinitionStoreException("I/O failure during classpath scanning", var14);    }}

这里扫描到了主类包下所有我们自定义的类:

最终将要创建的Bean全部处理成BeanDefinition注册到registry,这里经过多次递归上面的几个主要类的处理过程,最终创建所有194个Bean:

处理完所有的Bean后,PostProcessorRegistrationDelegate的方法继续执行,执行了其他几个后处理器,最后回到AbstractApplicationContext的refresh方法,最后回到SpringApplication的

this.refreshContext(context);

方法,最终完成所有方法,SpringBoot启动完成。

一定要断点调试,直接看源码臆想过程会出错!!

基础知识地址:

https://www.cnblogs.com/xiaoxi/p/6392154.html

https://blog.csdn.net/masterchiefcc/article/details/80358977

转载于:https://www.cnblogs.com/free-wings/p/10005763.html

Spring Boot源码分析相关推荐

  1. 精尽Spring Boot源码分析 - 内嵌Tomcat容器的实现

    概述 我们知道 Spring Boot 能够创建独立的 Spring 应用,内部嵌入 Tomcat 容器(Jetty.Undertow),让我们的 jar 无需放入 Servlet 容器就能直接运行. ...

  2. spring boot 源码分析(七) 事件机制 之 SpringApplicationEvent

    2019独角兽企业重金招聘Python工程师标准>>> 一.前言 前面的文章我们讲解了一下spring boot配置文件加载的相关源码分析,下面我们将从源码角度讲解一下spring  ...

  3. spring boot源码分析之SpringApplication

    spring boot提供了sample程序,学习spring boot之前先跑一个最简单的示例: /** Copyright 2012-2016 the original author or aut ...

  4. 实战:Spring Boot源码解读与原理分析

    承载着作者的厚望,掘金爆火小册同名读物<Spring Boot源码解读与原理剖析>正式出书! 本书前身是掘金社区销量TOP的小册--<Spring Boot源码解读与原理剖析> ...

  5. spring boot 源码解析23-actuate使用及EndPoint解析

    前言 spring boot 中有个很诱人的组件–actuator,可以对spring boot应用做监控,只需在pom文件中加入如下配置即可: <dependency><group ...

  6. 【赠书福利】掘金爆火小册同名《Spring Boot源码解读与原理剖析》正式出书了!...

    关注我们丨文末赠书 承载着作者的厚望,掘金爆火小册同名读物<Spring Boot源码解读与原理剖析>正式出书! 本书前身是掘金社区销量TOP的小册--<Spring Boot源码解 ...

  7. Spring Cloud源码分析(二)Ribbon(续)

    因文章长度限制,故分为两篇.上一篇:<Spring Cloud源码分析(二)Ribbon> 负载均衡策略 通过上一篇对Ribbon的源码解读,我们已经对Ribbon实现的负载均衡器以及其中 ...

  8. Spring AOP 源码分析 - 拦截器链的执行过程

    1.简介 本篇文章是 AOP 源码分析系列文章的最后一篇文章,在前面的两篇文章中,我分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在我们的得 ...

  9. Spring AOP 源码分析 - 创建代理对象

    1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...

  10. Spring AOP 源码分析 - 筛选合适的通知器

    1.简介 从本篇文章开始,我将会对 Spring AOP 部分的源码进行分析.本文是 Spring AOP 源码分析系列文章的第二篇,本文主要分析 Spring AOP 是如何为目标 bean 筛选出 ...

最新文章

  1. Android系列讲座(2):为TextView组件加上边框
  2. 0xc0000225无法进系统_冷却塔进风格栅结冰主要原因及对策
  3. 牛!这位斯坦福PhD新生的论文被引数:接近4万
  4. 什么是UUID及其实现代码
  5. 12c expdp ORA-31623 -又遇到BUG
  6. 4-1 复数类的运算符重载
  7. Fibonacci数列的幂和
  8. 确认! Python夺冠,Java“被迫”退出竞争舞台,网友:崩溃!
  9. 使用valgrind检查内存问题
  10. Oracle11默认用户名和密码
  11. java里面数字四舍五入,Java数字的四舍五入
  12. Python多线程好玩弹窗代码
  13. 吊炸天——74款APP完整源码
  14. Python excel转txt文件
  15. cpu压力测试 Android,测试CPU和GPU性能压力(StressMyPC)
  16. 计算机管理员权限win8,怎样获取win8.1超级管理员权限
  17. 微信小程序富文本编辑器
  18. kodi资源_Kodi——支持全平台的看片神器
  19. 笔记本右侧键盘数字打不出来
  20. MacOS / Vmware Fusion无法连接虚拟设备sata0:1,因为主机上没有相应设备

热门文章

  1. linux中crontab的用法
  2. r语言把多个图合并在一张图_R语言绘图 | 折线图画法,如何画出你满意的图?
  3. Linux主要的系统目录及其简单描述
  4. matlab 删掉空行,在MATLAB中使用XLSWRITE:如何删除空单元格?
  5. Hive cube,roll up入门案例
  6. openresty入门 方法及指令
  7. Linux开发_printf打印无消息或末尾带“#“or“%“
  8. 使用Opencv绘制灰度直方图/对比
  9. 什么是服务的熔断降级
  10. 实例化vue发生了什么?(详解vue生命周期)