springBoot-启动原理
阅读原文时间:2022年02月21日阅读:1

注:SpringBoot版本 2.6.2

SpringBoot的入口是从SpringApplication.run()传入我们的主启动类开始

@SpringBootApplication
public class LeeSpringbootApplication {

public static void main(String\[\] args) {  
    SpringApplication.run(LeeSpringbootApplication.class, args);  
}  

}

run()方法:

    1、初始化SrpingApplication对象

    2、执行run() 方法(primarySources:主启动类class)

public static ConfigurableApplicationContext run(Class[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}

1、初始化SrpingApplication对象

  1、设置应用类型,后面会根据类型初始化对应的环境,常用的一般都是servlet环境

  2、加载系统中引导器Bootstrapper(从META-INF/spring.factories中加载)

  3、初始化classpath下 META-INF/spring.factories 中已配置的ApplicationContextInitalizer

  4、初始化classpath下所以已配置的 ApplicationListener

  5、根据调用栈,设置 main 方法的类名

public SpringApplication(ResourceLoader resourceLoader, Class… primarySources) {
//设置资源加载器为null
this.resourceLoader = resourceLoader;
//断言加载资源不能为null
Assert.notNull(primarySources, "PrimarySources must not be null");
//将primarySources数组转换为list,最后放到LinkedHashSet集合中
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 1.1 推断应用类型,后面会根据类型初始化对应的环境,常用的一般都是servlet环境
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 1.2 加载系统中引导器Bootstrapper
this.bootstrapRegistryInitializers = new ArrayList<>(
getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
// 1.3 初始化classpath下 META-INF/spring.factories 中已配置的ApplicationContextInitalizer
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 1.4 初始化classpath下所以已配置的 ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 1.5 根据调用栈,设置 main 方法的类名
this.mainApplicationClass = deduceMainApplicationClass();
}

在执行 getSpringFactoriesInstances(BootstrapRegistryInitializer.class) 中会调用 loadSpringFactories() 方法遍历所有jar包中classpath下 META-INF/spring.factories文件,并保存在缓存中

private static Map> loadSpringFactories(ClassLoader classLoader) {
Map> result = cache.get(classLoader);
if (result != null) {
return result;
}

result = new HashMap<>();  
try {  
    Enumeration<URL> urls = classLoader.getResources(FACTORIES\_RESOURCE\_LOCATION);  
    while (urls.hasMoreElements()) {  
        URL url = urls.nextElement();  
        UrlResource resource = new UrlResource(url);  
        Properties properties = PropertiesLoaderUtils.loadProperties(resource);  
        for (Map.Entry<?, ?> entry : properties.entrySet()) {  
            String factoryTypeName = ((String) entry.getKey()).trim();  
            String\[\] factoryImplementationNames =  
                    StringUtils.commaDelimitedListToStringArray((String) entry.getValue());  
            for (String factoryImplementationName : factoryImplementationNames) {  
                result.computeIfAbsent(factoryTypeName, key -> new ArrayList<>())  
                        .add(factoryImplementationName.trim());  
            }  
        }  
    }

    // Replace all lists with unmodifiable lists containing unique elements  
    result.replaceAll((factoryType, implementations) -> implementations.stream().distinct()  
            .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)));  
    cache.put(classLoader, result);  
}  
catch (IOException ex) {  
    throw new IllegalArgumentException("Unable to load factories from location \[" +  
            FACTORIES\_RESOURCE\_LOCATION + "\]", ex);  
}  
return result;  

}

loadSpringFactories

2、执行run() 方法

  1、获取并启动监听器

  2、构造上下文环境

  3、初始化应用上下文

  4、刷新应用上下文前的准备阶段

  5、刷新上下文

  6、刷新应用上下文后的扩展接口

public ConfigurableApplicationContext run(String… args) {
//记录程序运行时间
long startTime = System.nanoTime();
// 创建 DefaultBootstrapContext 的一项
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
// ConfigurableApplicationContext spring的上下文
ConfigurableApplicationContext context = null;
configureHeadlessProperty();
// 1、获取并启动监听器
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 2、构造上下文环境
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
// 处理需要忽略的Bean
configureIgnoreBeanInfo(environment);
// 打印banner (springboot图标)
Banner printedBanner = printBanner(environment);
// 3、初始化应用上下文
context = createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
// 4、刷新应用上下文前的准备阶段
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 5、刷新上下文
refreshContext(context);
// 6、刷新应用上下文后的扩展接口
afterRefresh(context, applicationArguments);
// 记录执行时间
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
}
listeners.started(context, timeTakenToStartup);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}
try {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
listeners.ready(context, timeTakenToReady);
}
catch (Throwable ex) {
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
return context;
}

  2.1 加载监听器

    加载META-INF/spring.factories 中的 SpringApplicationRunListener,SpringApplicationRunListeners负责在springBoot启动的不同阶段,广播出不同的消息,传递给ApplicationListener监听器实现类

private SpringApplicationRunListeners getRunListeners(String[] args) {
Class[] types = new Class[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args),
this.applicationStartup);
}

    在 getSpringFactoriesInstances 中加载构建监听器对象并根据order进行排序

private Collection getSpringFactoriesInstances(Class type, Class[] parameterTypes, Object… args) {
ClassLoader classLoader = getClassLoader();
// Use names and ensure unique to protect against duplicates
Set names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}

  2.2 构造上下文环境

    根据之前标记的应用类型(SERVLET)创建相应的环境,并根据配置文件,配置相应的系统环境

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
// Create and configure the environment
// 创建并配置相应环境
ConfigurableEnvironment environment = getOrCreateEnvironment();
// 根据用户配置,配置系统环境
configureEnvironment(environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach(environment);
// 启动监听器,其中一个重要的监听器 ConfigFileApplicationListener 加载项目配置文件的监听器
listeners.environmentPrepared(bootstrapContext, environment);
DefaultPropertiesPropertySource.moveToEnd(environment);
Assert.state(!environment.containsProperty("spring.main.environment-prefix"),
"Environment prefix cannot be set via properties.");
bindToSpringApplication(environment);
if (!this.isCustomEnvironment) {
environment = convertEnvironment(environment);
}
ConfigurationPropertySources.attach(environment);
return environment;
}

  2.3 初始化应用上下文

    根据配置的应用类型(SERVLET)创建对应的context (AnnotationConfigServletWebServerApplicationContext) 并在父类 GenericApplicationContext 的构造方法中创建了DefaultListableBeanFactory(ioc容器)

protected ConfigurableApplicationContext createApplicationContext() {  
    return this.applicationContextFactory.create(this.webApplicationType);  
}

ApplicationContextFactory DEFAULT = (webApplicationType) -> {
try {
switch (webApplicationType) {
case SERVLET:
return new AnnotationConfigServletWebServerApplicationContext();
case REACTIVE:
return new AnnotationConfigReactiveWebServerApplicationContext();
default:
return new AnnotationConfigApplicationContext();
}
}
catch (Exception ex) {
throw new IllegalStateException("Unable create a default ApplicationContext instance, "
+ "you may need a custom ApplicationContextFactory", ex);
}
};

  2.4 刷新应用上下文前的准备阶段

主要完成应用上下文属性设置,并且将启动类生成实例对象保存到容器中。

private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
// 设置容器环境
context.setEnvironment(environment);
// 执行容器后置处理(主要设置转换器)
postProcessApplicationContext(context);
// 应用初始化器,执行容器中的 ApplicationContextInitializer 包括spring.factories
applyInitializers(context);
// 向各个容器中发送容器已经准备好的事件
listeners.contextPrepared(context);
bootstrapContext.close(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 将main函数中的args参数封装成单例Bean,注册到容器
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
// 将printedBanner 封装成单例Bean 注册到容器
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof AbstractAutowireCapableBeanFactory) {
((AbstractAutowireCapableBeanFactory) beanFactory).setAllowCircularReferences(this.allowCircularReferences);
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
}
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
// Load the sources
// 获取主启动类
Set sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
// 加载启动类,将启动类注册到容器
load(context, sources.toArray(new Object[0]));
// 发布容器中已加载的事件
listeners.contextLoaded(context);
}

    postProcessApplicationContext(context) 设置转换器

protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
if (this.beanNameGenerator != null) {
context.getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
this.beanNameGenerator);
}
if (this.resourceLoader != null) {
if (context instanceof GenericApplicationContext) {
((GenericApplicationContext) context).setResourceLoader(this.resourceLoader);
}
if (context instanceof DefaultResourceLoader) {
((DefaultResourceLoader) context).setClassLoader(this.resourceLoader.getClassLoader());
}
}
if (this.addConversionService) {
context.getBeanFactory().setConversionService(context.getEnvironment().getConversionService());
}
}

postProcessApplicationContext

    应用ApplicationContextInitializer

protected void applyInitializers(ConfigurableApplicationContext context) {  
    for (ApplicationContextInitializer initializer : getInitializers()) {  
        Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),  
                ApplicationContextInitializer.class);  
        Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");  
        initializer.initialize(context);  
    }  
}

applyInitializer

    getAllSource() 获取主启动类

public Set getAllSources() {
Set allSources = new LinkedHashSet<>();
if (!CollectionUtils.isEmpty(this.primarySources)) {
allSources.addAll(this.primarySources);
}
if (!CollectionUtils.isEmpty(this.sources)) {
allSources.addAll(this.sources);
}
return Collections.unmodifiableSet(allSources);
}

getAllSource

    load() 主要将主启动类生成实例对象保存在容器中,spring容器在启动的时候会将类解析成spring内部的BeanDefinition结构,并将BeanDefinition存储到DefaultListableBeanFactory的map中。

protected void load(ApplicationContext context, Object[] sources) {
if (logger.isDebugEnabled()) {
logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
}
// 创建 BeanDefinitionLoader
BeanDefinitionLoader loader = createBeanDefinitionLoader(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();
}

    getBeanDefinitionRegistry(context) 将上下文转换为 BeanDefinitionRegistry 类型

private BeanDefinitionRegistry getBeanDefinitionRegistry(ApplicationContext context) {
if (context instanceof BeanDefinitionRegistry) {
return (BeanDefinitionRegistry) context;
}
if (context instanceof AbstractApplicationContext) {
return (BeanDefinitionRegistry) ((AbstractApplicationContext) context).getBeanFactory();
}
throw new IllegalStateException("Could not locate BeanDefinitionRegistry");
}

getBeanDefinitionRegistry

getBeanDefinitionRegistry

    createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources) 创建BeanDefinitionLoader,其中创建一些Bean定义读取器。

protected BeanDefinitionLoader createBeanDefinitionLoader(BeanDefinitionRegistry registry, Object[] sources) {
return new BeanDefinitionLoader(registry, sources);
}

BeanDefinitionLoader(BeanDefinitionRegistry registry, Object… sources) {
Assert.notNull(registry, "Registry must not be null");
Assert.notEmpty(sources, "Sources must not be empty");
this.sources = sources;
// 创建注解形式的Bean定义读取器, eg:@Configuration @Bean @Component @Controller
this.annotatedReader = new AnnotatedBeanDefinitionReader(registry);
// 创建xml形式的Bean定义读取器
this.xmlReader = (XML_ENABLED ? new XmlBeanDefinitionReader(registry) : null);
this.groovyReader = (isGroovyPresent() ? new GroovyBeanDefinitionReader(registry) : null);
// 创建类路径扫描器
this.scanner = new ClassPathBeanDefinitionScanner(registry);
// 扫描器添加排除过滤器
this.scanner.addExcludeFilter(new ClassExcludeFilter(sources));
}

    loader.load()将启动类生成实例对象保存在容器中。

void load() {
for (Object source : this.sources) {
//source 为启动类
load(source);
}
}

private void load(Object source) {
Assert.notNull(source, "Source must not be null");
if (source instanceof Class) {
// 从class中加载
load((Class) source);
return;
}
if (source instanceof Resource) {
// 从 Resource 中加载
load((Resource) source);
return;
}
if (source instanceof Package) {
// 从 Package 中加载
load((Package) source);
return;
}
if (source instanceof CharSequence) {
// 从 CharSequence 中加载
load((CharSequence) source);
return;
}
throw new IllegalArgumentException("Invalid source type " + source.getClass());
}

private void load(Class source) {
if (isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
// Any GroovyLoaders added in beans{} DSL can contribute beans here
GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);
((GroovyBeanDefinitionReader) this.groovyReader).beans(loader.getBeans());
}
if (isEligible(source)) {
// 将启动类的 BeanDefinition 注册到 BeanDefinitionMap 中
this.annotatedReader.register(source);
}
}

load()

load

  2.5 刷新上下文

    主要逻辑为AbstractApplicationContext 对象的 refresh() 方法,进行整个容器的刷新过程,会调用spring中的refresh()方法,其中有13个关键方法,来完成整个
SpringBoot应用程序的启动。

private void refreshContext(ConfigurableApplicationContext context) {
if (this.registerShutdownHook) {
shutdownHook.registerApplicationContext(context);
}
refresh(context);
}

protected void refresh(ConfigurableApplicationContext applicationContext) {
applicationContext.refresh();
}

public final void refresh() throws BeansException, IllegalStateException {
try {
super.refresh();
}
catch (RuntimeException ex) {
WebServer webServer = this.webServer;
if (webServer != null) {
webServer.stop();
}
throw ex;
}
}

public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

    // Prepare this context for refreshing.  
    //1:准备刷新上下文环境  
    prepareRefresh();

    // Tell the subclass to refresh the internal bean factory.  
    //2:获取告诉子类初始化Bean工厂  不同工厂不同实现  
    ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

    // Prepare the bean factory for use in this context.  
    // 对bean工厂进行填充属性  
    prepareBeanFactory(beanFactory);

    try {  
        // Allows post-processing of the bean factory in context subclasses.  
        // 执行beanFactroy后置处理器  
        postProcessBeanFactory(beanFactory);

        StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");  
        // Invoke factory processors registered as beans in the context.  
        // 调用我们的bean工厂的后置处理器. 1. 会在此将class扫描成beanDefinition  2.bean工厂的后置处理器调用  
        invokeBeanFactoryPostProcessors(beanFactory);

        // Register bean processors that intercept bean creation.  
        // 注册我们bean的后置处理器  
        registerBeanPostProcessors(beanFactory);  
        beanPostProcess.end();

        // Initialize message source for this context.  
        // 初始化国际化资源处理器.  
        initMessageSource();

        // Initialize event multicaster for this context.  
        // 创建事件多播器  
        initApplicationEventMulticaster();

        // Initialize other special beans in specific context subclasses.  
        // 这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomcat的.  
        onRefresh();

        // Check for listener beans and register them.  
        //把我们的事件监听器注册到多播器上  
        registerListeners();

        // Instantiate all remaining (non-lazy-init) singletons.  
        // 实例化我们剩余的单实例bean.  
        finishBeanFactoryInitialization(beanFactory);

        // Last step: publish corresponding event.  
        // 最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)  
        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) 改方法会解析核心启动类中 @SpringBootApplication实现自动配置

    Ioc容器的初始化包括三个步骤,该三个步骤在 invokeBeanFactoryPostProcessors 中完成

      1、Resource定位

        在SpringBoot中,包扫描是从主类所在包开始扫描,prepareContext()方法中,会将主类解析成BeanDefinition保存在容器中,然后在refresh()方法的invokeBeanFactoryPostProcessors()方法中解析主类的BeanDefinition获取basePackage的路径。这样就完成了定位的过程。

        SpringBoot的各种starter是通过SPI扩展机制实现的自动装配,SpringBoot的自动装配同样也是在invokeBeanFactoryPostProcessors()方法中实现的。        在SpringBoot中有很多的@EnableXXX注解,其底层是@Import注解,在invokeBeanFactoryPostProcessors()方法中也实现了对该注解指定的配置类的定位加载。

        常规在SpringBoot中有三种定位方法:主类所在的包、SPI扩展机制实现的自动装配、@Import注解指定的类

        SPI ,全称为 Service Provider Interface,是一种服务发现机制。它通过在ClassPath路径下的META-INF/services文件夹查找文件,自动加载文件里所定义的类,也可以这样理解:SPI是“基于接口的编程+策略模式+配置文件”组成实现的动态加载机制。

      2、BeanDefinition的载入

        SpringBoot会将通过定位得到的basePackage的路径拼装成 classpath:com/***/.class 的形式,然后 PathMatchingResourcePatternResolver类会将该路径下所有的 .class 文件加载进来,然后进行遍历判断是否含有 @Component 注解,如果有就是要装载的 BeanDefinition。

      3、注册Beanfinition

        注册过程是将载入过程中解析得到的BeanDefinition向IOC容器进行注册。通过上下文分析,在容器中将BeanDefinition注入到一个ConcurrenHashMap中,IOC容器通过这个map来保存BeanDefinition数据。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime  
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)  
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD\_TIME\_WEAVER\_BEAN\_NAME)) {  
    beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));  
    beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));  
}  

}

// PostProcessorRegistrationDelegate
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {

// 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 = new HashSet<>();

if (beanFactory instanceof BeanDefinitionRegistry) {  
    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;  
    List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();  
    List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

    for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {  
        if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {  
            BeanDefinitionRegistryPostProcessor registryProcessor =  
                    (BeanDefinitionRegistryPostProcessor) postProcessor;  
            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 = new ArrayList<>();

    // 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.  
    boolean reiterate = 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 = new ArrayList<>();  
List<String> orderedPostProcessorNames = new ArrayList<>();  
List<String> nonOrderedPostProcessorNames = new ArrayList<>();  
for (String ppName : postProcessorNames) {  
    if (processedBeans.contains(ppName)) {  
        // skip - already processed in first phase above  
    }  
    else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {  
        priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));  
    }  
    else if (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 = new ArrayList<>(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 = new ArrayList<>(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();  

}

private static void invokeBeanDefinitionRegistryPostProcessors(
Collection postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {

for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {  
    StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")  
            .tag("postProcessor", postProcessor::toString);  
    // 解析注解  
    postProcessor.postProcessBeanDefinitionRegistry(registry);  
    postProcessBeanDefRegistry.end();  
}  

}

invokeBeanFactoryPostProcessors

   实现自动装配:

    invokeBeanFactoryPostProcessors()方法主要是对 ConfigurationClassPostProcessor 类的处理,这是BeanDefinitionRegistryPostProcessor的子类,BeanDefinitionRegistryPostProcessor 是BeanDefinitionRegistryPostProcessor 的子类,调用BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry()方法,会解析 @PropertySource @ComponentScans @ComponentScan @Bean @Import等注解

  refresh() -> AbstractApplicationContext.invokeBeanFactoryPostProcessors(beanFactory)
  -> invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup())
  -> postProcessor.postProcessBeanDefinitionRegistry(registry) (ConfigurationClassPostProcessor类下的方法)
  -> processConfigBeanDefinitions(registry) -> new ConfigurationClassParser() (解析@Configuration 标注的类)
  -> parser.parse(candidates) (解析启动类上的注解)
  -> this.reader.loadBeanDefinitions(configClasses) (生效自动配置类)

// ConfigurationClassPostProcessor
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);

processConfigBeanDefinitions(registry);  

}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List configCandidates = new ArrayList<>();
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)) {  
        configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));  
    }  
}

// Return immediately if no @Configuration classes were found  
if (configCandidates.isEmpty()) {  
    return;  
}

// Sort by previously determined @Order value, if applicable  
configCandidates.sort((bd1, bd2) -> {  
    int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());  
    int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());  
    return Integer.compare(i1, i2);  
});

// Detect any custom bean name generation strategy supplied through the enclosing application context  
SingletonBeanRegistry sbr = null;  
if (registry instanceof SingletonBeanRegistry) {  
    sbr = (SingletonBeanRegistry) registry;  
    if (!this.localBeanNameGeneratorSet) {  
        BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(  
                AnnotationConfigUtils.CONFIGURATION\_BEAN\_NAME\_GENERATOR);  
        if (generator != null) {  
            this.componentScanBeanNameGenerator = generator;  
            this.importBeanNameGenerator = generator;  
        }  
    }  
}

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

// Parse each @Configuration class  
ConfigurationClassParser parser = new ConfigurationClassParser(  
        this.metadataReaderFactory, this.problemReporter, this.environment,  
        this.resourceLoader, this.componentScanBeanNameGenerator, registry);

Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);  
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());  
do {  
    StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");  
    //获取所有bean的全路径(解析各类注解)  
    parser.parse(candidates);  
    parser.validate();

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

    // Read the model and create bean definitions based on its content  
    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);  
    processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();

    candidates.clear();  
    if (registry.getBeanDefinitionCount() > candidateNames.length) {  
        String\[\] newCandidateNames = registry.getBeanDefinitionNames();  
        Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));  
        Set<String> alreadyParsedClasses = new HashSet<>();  
        for (ConfigurationClass configurationClass : alreadyParsed) {  
            alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());  
        }  
        for (String candidateName : newCandidateNames) {  
            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());

// 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();  
}  

}

postProcessBeanDefinitionRegistry

    parser.parse(candidates) 从启动类开始解析各种注解(@PropertySource @ComponentScan @Import @ImportResource @Bean),加载配置类,在processImports(configClass, sourceClass, getImports(sourceClass), filter, true)中对启动类进行解析,加载其中的@Import注解的类

public void parse(Set configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
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);
}
}

this.deferredImportSelectorHandler.process();  

}

protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
protected void processConfigurationClass(ConfigurationClass configClass, Predicate filter) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}

ConfigurationClass existingClass = this.configurationClasses.get(configClass);  
if (existingClass != null) {  
    if (configClass.isImported()) {  
        if (existingClass.isImported()) {  
            existingClass.mergeImportedBy(configClass);  
        }  
        // Otherwise ignore new imported config class; existing non-imported class overrides it.  
        return;  
    }  
    else {  
        // Explicit bean definition found, probably replacing an import.  
        // Let's remove the old one and go with the new one.  
        this.configurationClasses.remove(configClass);  
        this.knownSuperclasses.values().removeIf(configClass::equals);  
    }  
}

// Recursively process the configuration class and its superclass hierarchy.  
SourceClass sourceClass = asSourceClass(configClass, filter);  
do {  
    sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);  
}  
while (sourceClass != null);

this.configurationClasses.put(configClass, configClass);  

}

protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate filter)
throws IOException {

if (configClass.getMetadata().isAnnotated(Component.class.getName())) {  
    // Recursively process any member (nested) classes first  
    processMemberClasses(configClass, sourceClass, filter);  
}

// Process any @PropertySource annotations  
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");  
    }  
}

// Process any @ComponentScan annotations  
// 对启动类下的所有 @ComponentScan 进行解析加载,包含(@RestController @Service等)  
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(  
        sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);  
if (!componentScans.isEmpty() &&  
        !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER\_BEAN)) {  
    for (AnnotationAttributes componentScan : componentScans) {  
        // The config class is annotated with @ComponentScan -> perform the scan immediately  
        Set<BeanDefinitionHolder> 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());  
            }  
        }  
    }  
}

// Process any @Import annotations  
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

// Process any @ImportResource annotations  
AnnotationAttributes importResource =  
        AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);  
if (importResource != null) {  
    String\[\] resources = importResource.getStringArray("locations");  
    Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");  
    for (String resource : resources) {  
        String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);  
        configClass.addImportedResource(resolvedResource, readerClass);  
    }  
}

// Process individual @Bean methods  
Set<MethodMetadata> 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;  

}

parse

    通过getImport(sourceClass) 解析启动类上的注解,获取到其中被@Import注解的类,即AutoConfigurationPackages、AutoConfigurationImportSelector

    启动类上@SpringBootApplication注解为组合注解

               

    @SpringBootConfiguration:其实质是一个 @Configuration 注解,表明该类是一个配置类

    @EnableAutoConfiguration:开启了自动配置功能

      @AutoConfigurationPackage:被该注解标注的类即主配置类,将主配置类所在的包当作base-package

      
    @ComponentScan:直接向容器中注入指定的组件

  在解析@Import注解时,会有一个getImports()方法,从启动类开始递归解析注解,把所有包含@Import的注解都解析到,然后再processImport()方法中对@Import注解的类进行分类,此处主要识别的是AutoConfigurationImportSelector 归属于ImportSelector的子类,在后续的过程中会调用 DeferredImprotSelectorHandler中的process()方法,来完成EnableAutoConfiguration的加载。

private Set getImports(SourceClass sourceClass) throws IOException {
Set imports = new LinkedHashSet<>();
Set visited = new LinkedHashSet<>();
collectImports(sourceClass, imports, visited);
return imports;
}
private void collectImports(SourceClass sourceClass, Set imports, Set visited)
throws IOException {

if (visited.add(sourceClass)) {  
    for (SourceClass annotation : sourceClass.getAnnotations()) {  
        String annName = annotation.getMetadata().getClassName();  
        if (!annName.equals(Import.class.getName())) {  
            collectImports(annotation, imports, visited);  
        }  
    }  
    imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));  
}  

}

getImports

  执行this.deferredImportSelectorHandler.process()方法进行实现自动装配

public void process() {
List deferredImports = this.deferredImportSelectors;
this.deferredImportSelectors = null;
try {
if (deferredImports != null) {
DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
deferredImports.forEach(handler::register);
handler.processGroupImports();
}
}
finally {
this.deferredImportSelectors = new ArrayList<>();
}
}

// ConfigurationClassParser
public void processGroupImports() {
for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
Predicate exclusionFilter = grouping.getCandidateFilter();
grouping.getImports().forEach(entry -> {
ConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata());
try {
// 处理配置类上的注解
processImports(configurationClass, asSourceClass(configurationClass, exclusionFilter),
Collections.singleton(asSourceClass(entry.getImportClassName(), exclusionFilter)),
exclusionFilter, false);
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configurationClass.getMetadata().getClassName() + "]", ex);
}
});
}
}

// DeferredImportSelectorGrouping
public Iterable getImports() {
for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {
// 遍历DeferredImportSelectorHolder对象集合deferredImports,deferrdImports集合装了各种ImportSelector(AutoConfigurationImportSelect)
this.group.process(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getImportSelector());
}
// 经过上面处理,然后再进行选择导入哪写配置类
return this.group.selectImports();
}
//AutoConfigurationImportSelector
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()));
// 获取自动配置类放入 AutoConfigurationEntry 对象中
AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
.getAutoConfigurationEntry(annotationMetadata);
// 将封装了自动配置类的 AutoConfigurationEntry 对象装进 autoConfigurationEntries 集合
this.autoConfigurationEntries.add(autoConfigurationEntry);
// 遍历刚获取的自动配置类
for (String importClassName : autoConfigurationEntry.getConfigurations()) {
// 将符合条件的自动配置类作为 key,annotationMetadata作为值放进 entries 集合中
this.entries.putIfAbsent(importClassName, annotationMetadata);
}
}
// AutoConfigurationImportSelector
public Iterable selectImports() {
if (this.autoConfigurationEntries.isEmpty()) {
return Collections.emptyList();
}
.getAutoConfigurationEntry(annotationMetadata);
// 得到所有要排除的自动配置类集合
Set allExclusions = this.autoConfigurationEntries.stream()
.map(AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());
.getAutoConfigurationEntry(annotationMetadata);
// 得到经过过滤后所有符合条件的自动配置类集合
Set processedConfigurations = this.autoConfigurationEntries.stream()
.map(AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream)
.collect(Collectors.toCollection(LinkedHashSet::new));
.getAutoConfigurationEntry(annotationMetadata);
// 移除需要排除的自动配置类
processedConfigurations.removeAll(allExclusions);

        .getAutoConfigurationEntry(annotationMetadata);  
// 对标注有 @Order注解的自动配置类进行排序  
return sortAutoConfigurations(processedConfigurations, getAutoConfigurationMetadata()).stream()  
        .map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName))  
        .collect(Collectors.toList());  

}

private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection importCandidates, Predicate exclusionFilter,
boolean checkForCircularImports) {

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

if (checkForCircularImports && isChainedImportOnStack(configClass)) {  
    this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));  
}  
else {  
    this.importStack.push(configClass);  
    try {  
        for (SourceClass candidate : importCandidates) {  
            if (candidate.isAssignable(ImportSelector.class)) {  
                // Candidate class is an ImportSelector -> delegate to it to determine imports  
                Class<?> candidateClass = candidate.loadClass();  
                ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,  
                        this.environment, this.resourceLoader, this.registry);  
                Predicate<String> selectorFilter = selector.getExclusionFilter();  
                if (selectorFilter != null) {  
                    exclusionFilter = exclusionFilter.or(selectorFilter);  
                }  
                if (selector instanceof DeferredImportSelector) {  
                    this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);  
                }  
                else {  
                    String\[\] importClassNames = selector.selectImports(currentSourceClass.getMetadata());  
                    Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);  
                    processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);  
                }  
            }  
            else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {  
                // Candidate class is an ImportBeanDefinitionRegistrar ->  
                // delegate to it to register additional bean definitions  
                Class<?> candidateClass = candidate.loadClass();  
                ImportBeanDefinitionRegistrar registrar =  
                        ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,  
                                this.environment, this.resourceLoader, this.registry);  
                configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());  
            }  
            else {  
                // Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->  
                // process it as an @Configuration class  
                this.importStack.registerImport(  
                        currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());  
                processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);  
            }  
        }  
    }  
    catch (BeanDefinitionStoreException ex) {  
        throw ex;  
    }  
    catch (Throwable ex) {  
        throw new BeanDefinitionStoreException(  
                "Failed to process import candidates for configuration class \[" +  
                configClass.getMetadata().getClassName() + "\]", ex);  
    }  
    finally {  
        this.importStack.pop();  
    }  
}  

}

  执行 this.reader.loadBeanDefinitions(configClasses) 对自动配置类进行生效,生成Bean对象。

自动装配原理总结:

1、当启动SpringBoot应用程序时,会创建 SpringApplication 对象,在对象的构造方法中进行某些参数的初始化工作,最主要的是判断当前应用程序的类型及初始化器和监听器,在这个过程中会加载整个应用程序的 META-INF/spring.factories 文件,将文件的内容保存到缓存中(Map>> cache ),方便后续获取。

  2、SpringApplication对象创建完成后,开始执行run() 方法来完成整个启动。启动过程中最主要的是有两个方法:prepareContext()、refreshContext(),在这两个方法中完成了自动装配的核心功能。在其之前的处理逻辑中包含了上下文对象的创建,banner的打印等各个准备工作。

  3、在prepareContext()方法中主要完成的是对上下文对象的初始化操作,包含了属性值的设置(比如环境对象)。在整个过程中load()方法完成将当前启动类作为一个BeanDefinition注册到registry中,方便后续在进行BeanFactory调用执行时找到对应的主类,来完成对 @SpringBootApplication @EnableAutoConfiguration等注解的解析工作。

  4、在refreshContext()方法中会进行整个容器的刷新过程,会调用spring中的refresh()方法。refresh()中有13个关键方法,在自动装配过程中,会调用invokeBeanFactoryPostProcessors()方法主要是对 ConfigurationClassPostProcessor 类的处理,这是BeanDefinitionRegistryPostProcessor的子类,BeanDefinitionRegistryPostProcessor 是BeanDefinitionRegistryPostProcessor 的子类,调用BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry()方法,会解析@PropertySource @ComponentScans @ComponentScan @Bean @Import等注解。

  5、在解析@Import注解时,会有一个getImports()方法,从启动类开始递归解析注解,把所有包含@Import的注解都解析到,然后再processImport()方法中对@Import注解的类进行分类,此处主要识别的是AutoConfigurationImportSelector 归属于ImportSelector的子类,在后续的过程中会调用 DeferredImprotSelectorHandler中的process()方法,来完成EnableAutoConfiguration的加载。