一、简易流程描述
启动类->@SpringBootApplication->@EnableAutoConfiguration-> @Import(AutoConfigurationImportSelector.class)->getCandidateConfigurations
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {// 从 Spring.factories 中 获取 EnableAutoConfiguration 下的所有类List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader());Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "+ "are using a custom packaging, make sure that file is correct.");return configurations;}
�getSpringFactoriesLoaderFactoryClass
protected Class<?> getSpringFactoriesLoaderFactoryClass() {return EnableAutoConfiguration.class;}
从 Spring.factories 中 获取 EnableAutoConfiguration 下的所有类,并进行bean的加载
二、详细描述
1、SpringApplication

primarySources 是当前传入的主类信息
mainApplicationClass 是 主类的 Class信息
2、run方法
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {context.setEnvironment(environment);// 添加一些 post processing 到 context 中postProcessApplicationContext(context);// 在所有的初始化器中添加 context(initializer.initialize(context);)applyInitializers(context);// 在所有的监听器中添加 context到对应的事件中 (listener.contextPrepared(context);)listeners.contextPrepared(context);if (this.logStartupInfo) {logStartupInfo(context.getParent() == null);logStartupProfileInfo(context);}// Add boot specific singleton beans// 获取spring的bean工厂,这里默认是DefaultListableBeanFactoryConfigurableListableBeanFactory beanFactory = context.getBeanFactory();beanFactory.registerSingleton("springApplicationArguments", applicationArguments);// beanFactory 的一些信息的设置if (printedBanner != null) {beanFactory.registerSingleton("springBootBanner", printedBanner);}if (beanFactory instanceof DefaultListableBeanFactory) {((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}if (this.lazyInitialization) {context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());}// Load the sourcesSet<Object> sources = getAllSources();Assert.notEmpty(sources, "Sources must not be empty");// 如果包含了 @Component 注解,则将启动类注册到 AnnotatedBeanDefinitionReader 中load(context, sources.toArray(new Object[0]));// 监听器,发布事件 (listeners.contextLoaded(context))listeners.contextLoaded(context);}
直接跳到 prepareContext —> getAllSources
这里获取到主类
public Set<Object> getAllSources() {Set<Object> allSources = new LinkedHashSet<>();// 将主类加到 set 中并返回if (!CollectionUtils.isEmpty(this.primarySources)) {allSources.addAll(this.primarySources);}if (!CollectionUtils.isEmpty(this.sources)) {allSources.addAll(this.sources);}return Collections.unmodifiableSet(allSources);}
如果包含了 @Component 注解,则将启动类注册到 AnnotatedBeanDefinitionReader 中,此时主类就会被注册到AnnotatedBeanDefinitionReader中去,内部会注册到 Beanfactory 中去。
private final AnnotatedBeanDefinitionReader annotatedReader;// Load beans into the application context.// source 就是主类private int load(Class<?> source) {if (isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {// Any GroovyLoaders added in beans{} DSL can contribute beans hereGroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);load(loader);}if (isComponent(source)) {// 如果包含了 @Component 注解,则将启动类注册到 AnnotatedBeanDefinitionReader 中this.annotatedReader.register(source);return 1;}return 0;}
主要实现点
接着直接到refresh�Context中调用spring的refresh的invokeBeanFactoryPostProcessors方法中,(这个方法只有springboot才有实现,spring的这个方法没有实现)
这里回顾 https://www.yuque.com/wangchao-volk4/fdw9ek/ppw8cy#ObsXa
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 (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}
getBeanFactoryPostProcessors
�
接着 执行 invokeBeanFactoryPostProcessors—》invokeBeanDefinitionRegistryPostProcessors—》_postProcessor.postProcessBeanDefinitionRegistry(registry)—》processConfigBeanDefinitions(在方法 ConfigurationClassPostProcessor 中)
在 parser.parse(candidates)_; 方法中解析主类
接着在parse中 执行doProcessConfigurationClass
doProcessConfigurationClass 内部使用了方法 processImports

接着获取到主类中@Import中的 AutoConfigurationImportSelector.class 和AutoConfigurationPackages.Registrar.class。
doProcessConfigurationClass 执行完后回到 parser.parse(org.springframework.context.annotation.ConfigurationClassParser#parse(java.util.Set
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();}
使用this.deferredImportSelectorHandler.process(); 处理刚才导入的@Import中的类。
process—》handler.processGroupImports()—》grouping.getImports()
�group.process(org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.AutoConfigurationGroup#process)
终于找到了getCandidateConfigurations方法。
从 Spring.factories 中 获取 EnableAutoConfiguration 下的所有类。
�
�
�
�
�
�
�
�
