springBoot-启动原理

博客 动态
0 223
羽尘
羽尘 2022-02-21 14:55:41
悬赏:0 积分 收藏

springBoot-启动原理

注:SpringBoot版本 2.6.2

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

@SpringBootApplicationpublic 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<String, List<String>> loadSpringFactories(ClassLoader classLoader) {    Map<String, List<String>> 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 <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {    ClassLoader classLoader = getClassLoader();    // Use names and ensure unique to protect against duplicates    Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));    List<T> 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<Object> 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<Object> getAllSources() {    Set<Object> 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()));    }}// PostProcessorRegistrationDelegatepublic static void invokeBeanFactoryPostProcessors(        ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> 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<? extends BeanDefinitionRegistryPostProcessor> 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) (生效自动配置类)
//     ConfigurationClassPostProcessorpublic 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<BeanDefinitionHolder> 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<BeanDefinitionHolder> 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<String> 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<String> 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<SourceClass> getImports(SourceClass sourceClass) throws IOException {    Set<SourceClass> imports = new LinkedHashSet<>();    Set<SourceClass> visited = new LinkedHashSet<>();    collectImports(sourceClass, imports, visited);    return imports;}    private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> 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<DeferredImportSelectorHolder> 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<>();    }}// ConfigurationClassParserpublic void processGroupImports() {    for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {        Predicate<String> 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);            }        });    }}// DeferredImportSelectorGroupingpublic Iterable<Group.Entry> getImports() {    for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {        // 遍历DeferredImportSelectorHolder对象集合deferredImports,deferrdImports集合装了各种ImportSelector(AutoConfigurationImportSelect)        this.group.process(deferredImport.getConfigurationClass().getMetadata(),                deferredImport.getImportSelector());    }    // 经过上面处理,然后再进行选择导入哪写配置类    return this.group.selectImports();}//AutoConfigurationImportSelectorpublic 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);    }}// AutoConfigurationImportSelectorpublic Iterable<Entry> selectImports() {    if (this.autoConfigurationEntries.isEmpty()) {        return Collections.emptyList();    }            .getAutoConfigurationEntry(annotationMetadata);    // 得到所有要排除的自动配置类集合    Set<String> allExclusions = this.autoConfigurationEntries.stream()            .map(AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());            .getAutoConfigurationEntry(annotationMetadata);    // 得到经过过滤后所有符合条件的自动配置类集合    Set<String> 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<SourceClass> importCandidates, Predicate<String> 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();        }    }}    
View Code

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

 

自动装配原理总结:

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

posted @ 2022-02-21 13:56 sun丶牧羊人 阅读(31) 评论(0) 编辑 收藏 举报
回帖
    羽尘

    羽尘 (王者 段位)

    2335 积分 (2)粉丝 (11)源码

     

    温馨提示

    亦奇源码

    最新会员