读完这章,你还敢说你不会SpringBoot源码?

Posted 守夜人爱吃兔子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读完这章,你还敢说你不会SpringBoot源码?相关的知识,希望对你有一定的参考价值。

前言

笔者把之前的Spring的格式重新排版,并且细致到一行一个讲解,希望大家喜欢。
大家使用Spring Boot这么久了,有没有知道Spring Boot的启动流程是怎样的呢?Spring是如何扫描到使用@Component的类并且把它放进BeanFactory呢?它是如何启动的呢?现在我们就一起看看。本系列会分几个章节去讲述这个Spring Boot的启动过程。由于写这篇文章的时候,在很多环境写过,所以可能由于Spring Boot版本不同代码也不同,但是思路是一样的。

1.创建SpringApplication对象

// 1.main方法
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class DemoApplication {

    public static void main(String[] args) {
        // 启动入口,请点击run方法
        SpringApplication.run(DemoApplication.class, args);
    }
}
// 2.main方法进来后先创建一个实例new SpringApplication 蹩脚翻译一下
/**
 * 创建一个新的SpringApplication实例也就是要new SpringApplication(),并且定义主要的类作为Bean的加载来源
 */
/**
 * Create a new {@link SpringApplication} instance. The application context will load
 * beans from the specified primary sources (see {@link SpringApplication class-level}
 * documentation for details. The instance can be customized before calling
 * {@link #run(String...)}.
 * @param resourceLoader the resource loader to use
 * @param primarySources the primary bean sources
 * @see #run(Class, String[])
 * @see #setSources(Set)
 */
@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
	this.resourceLoader = resourceLoader;
	Assert.notNull(primarySources, "PrimarySources must not be null");
	// 设置类入口也就是启动类
	this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
	// 设置这个应用的类型,分别为SERVLET、NONE、REACTIVE。具体可以看WebApplicationType枚举类
	this.webApplicationType = WebApplicationType.deduceFromClasspath();
	// 设置初始化器,这个getSpringFactoriesInstances()方法是从spring.factories中读取
	setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
	// 设置监听器,更上面一样也就是只要看到这个方法就是从spring.factories中读取要的类并且加载
	setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
	this.mainApplicationClass = deduceMainApplicationClass();
}

2.在SpringApplication对象调用run()

/**
 * 1.跑run方法
 */
public ConfigurableApplicationContext run(String... args) {
	StopWatch stopWatch = new StopWatch();
	// 开启计时器
	stopWatch.start();
	ConfigurableApplicationContext context = null;
	Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
	// 配置一些外设
	configureHeadlessProperty();
	// 获取监听器,这个getRunlisteners方法里面也是一样获取监听器
	SpringApplicationRunListeners listeners = getRunListeners(args);
	// 监听器开始执行
	listeners.starting();
	try {
		ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
		ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
		configureIgnoreBeanInfo(environment);
		// 打印banner
		Banner printedBanner = printBanner(environment);
		// 创建应用上下文,请看2
		context = createApplicationContext();
		// 加载异常报告期
		exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
				new Class[] { ConfigurableApplicationContext.class }, context);
		// 准备上下文,请看3
		prepareContext(context, environment, listeners, applicationArguments, printedBanner);
		// 刷新上下文
		refreshContext(context);
		afterRefresh(context, applicationArguments);
		stopWatch.stop();
		if (this.logStartupInfo) {
			new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
		}
		listeners.started(context);
		callRunners(context, applicationArguments);
	}
	catch (Throwable ex) {
		handleRunFailure(context, ex, exceptionReporters, listeners);
		throw new IllegalStateException(ex);
	}

	try {
		listeners.running(context);
	}
	catch (Throwable ex) {
		handleRunFailure(context, ex, exceptionReporters, null);
		throw new IllegalStateException(ex);
	}
	return context;
}
/**
 * 2.这个方法是从创建SpringApplication实例加载的应用类型去创建不同的上下文实例,这里由于是SERVLET类型所以会创建
 */
protected ConfigurableApplicationContext createApplicationContext() {
	Class<?> contextClass = this.applicationContextClass;
	if (contextClass == null) {
		try {
		switch (this.webApplicationType) {
			case SERVLET:
				// org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
				// 叫做注解配置上下文实例(蹩脚翻译)
				contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
				break;
			case REACTIVE:
				contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
				break;
			default:
				contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
			}
		}
		catch (ClassNotFoundException ex) {
			throw new IllegalStateException(
					"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
		}
	}
	return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
/**
 * 3.准备上下文,这里其实挺重要的,讲述了启动类如何加载到BeanFactory
 * 其实就一个重点,在load()这个方法里面
 */
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
		SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
	context.setEnvironment(environment);
	postProcessApplicationContext(context);
	applyInitializers(context);
	listeners.contextPrepared(context);
	if (this.logStartupInfo) {
		logStartupInfo(context.getParent() == null);
		logStartupProfileInfo(context);
	}
	// Add boot specific singleton beans
	// 这里context因为是AnnotationConfigServletWebServerApplicationContext
	// 所以他继承于ServletWebServerApplicationContext
	// ServletWebServerApplicationContext继承GenericWebApplicationContext
	// GenericWebApplicationContext继承GenericApplicationContext
	// 所以他的beanFactory是默认的private final DefaultListableBeanFactory beanFactory;
	ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
	beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
	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 sources
	Set<Object> sources = getAllSources();
	Assert.notEmpty(sources, "Sources must not be empty");
	// 这个方法讲述了启动类如何注册到beanFactory里面,为下面的refreshContext做了铺垫
	// 而且这个load方法里面还有启动类如何注册到BeanDefinition里面去的,去看4
	load(context, sources.toArray(new Object[0]));
	listeners.contextLoaded(context);
}
/**
 * 4.这里就先说下doRegisterBean()
 * 每个bean被执行doGetBean方法前都是要把Bean的定义信息拿到,也就是通俗的BeanDefinition,类的元数据
 * 而AnnotatedGenericBeanDefinition就是为了公开这些类元数据做的接口
 * 当adb和beanName一起在BeanDefinitionHolder初始化的时候
 */
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
		@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
		@Nullable BeanDefinitionCustomizer[] customizers) {
	// 定义bean的元数据对象,下面都是获取bean名字之类的
	AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
	if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
		return;
	}
	abd.setInstanceSupplier(supplier);
	ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
	abd.setScope(scopeMetadata.getScopeName());
	String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
	AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
	if (qualifiers != null) {
		for (Class<? extends Annotation> qualifier : qualifiers) {
			if (Primary.class == qualifier) {
				abd.setPrimary(true);
			}
			else if (Lazy.class == qualifier) {
				abd.setLazyInit(true);
			}
			else {
				abd.addQualifier(new AutowireCandidateQualifier(qualifier));
			}
		}
	}
	if (customizers != null) {
		for (BeanDefinitionCustomizer customizer : customizers) {
			customizer.customize(abd);
		}
	}
	// 当元数据对象与beanName创建了BeanDefinitionHolder
	// 他会把一些alias和beanName全部保存下来
	BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
	definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
	// 这里就会正式把此bean注册到this.beanDefinitionMap和this.beanDefinitionNames属性里面
	// 而这两个属性就是刚刚的默认beanFactory也就是DefaultListableBeanFactory.class
	BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

3.核心方法refreshContext

/**
 * 1.此方法其实就是Spring整个启动过程或者说ioc等等的核心流程了
 * 这个方法分几步去讲解
 */
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		// 准备上下文
		prepareRefresh();
		// Tell the subclass to refresh the internal bean factory.
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
		// Prepare the bean factory for use in this context.
		prepareBeanFactory(beanFactory);
		try {
			// Allows post-processing of the bean factory in context subclasses.
			postProcessBeanFactory(beanFactory);
			// Invoke factory processors registered as beans in the context.
			// 这个方法是扫描所有的Bean和加载所有的Bean
			invokeBeanFactoryPostProcessors(beanFactory);
			

			// Instantiate all remaining (non-lazy-init) singletons.
			// 前面是扫描和加载,这个步骤就是真正的创建Bean实例了
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			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();
		}
	}
}
/**
 * 2.这里进来就是beanFactory增强器加载
 */
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	// getBeanFactoryPostProcessors()这个方法就是获取当前所有的beanFactory增强器进去可以看看,目前默认有3个
	// 1.SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor在prepareContext中的applyInitializers插入
	// 2.ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor在prepareContext中的applyInitializers插入
	// 3.ConfigFileApplicationListener$PropertySourceOrderingPostProcessor在prepareContext最后一行listeners.contextLoaded(context)插入
	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()));
	}
}
/**
 * 3.这方法重中之重,里面包涵了大量的操作我们来一起看看
 */
public static void invokeBeanFactoryPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
	// Invoke BeanDefinitionRegistryPostProcessors first, if any.
	Set<String> processedBeans = new HashSet<>();
	// 这个context是AnnotationConfigServletWebServerApplicationContext实例他继承的类有BeanDefinitionRegistry接口
	// 所以这里一定会进来
	if (beanFactory instanceof BeanDefinitionRegistry) {
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
		// 这个循环是把那3个增强器分类
		// CachingMetadataReaderFactoryPostProcessor实现BeanDefinitionRegistryPostProcessor
		// ConfigurationWarningsPostProcesso实现BeanDefinitionRegistryPostProcessor
		// PropertySourceOrderingPostProcessor实现BeanFactoryPostProcessor
		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
				BeanDefinitionRegistryPostProcessor registryProcessor =
						(BeanDefinitionRegistryPostProcessor) postProcessor;
				// 这里把BeanDefinition注册进去
				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.
		// 这里获取到的beanName不是刚刚的增强器而是常量org.springframework.context.annotation.internalConfigurationAnnotationProcessor
		// 并且下面这个循环会把ConfigurationClassPostProcessor加载出来。
		// 那么大家会问ConfigurationClassPostProcessor什么时候加载的呢?
		// createApplicationContext这个方法还记得吧!就是在这里加载的当Spring选择了Servlet模式就会加载配置
		// CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME就会作为beanNamePut进beanFactory
		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);
		// 当ConfigurationClassPostProcessor回去跑processConfigBeanDefinitions方法,跳去4
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		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);
		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);
			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();
}
/**
 * 4.这里就是把启动类选出来并且开始ComponentScan的地方,自动装配也是这里完成的@Import
 */
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
	List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
	String[] candidateNames = registry.getBeanDefinitionNames();
	//configCandidates这会加入启动类
	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));
		}
	}
	/**
	 * 省略代码
	 */
	// Parse each @Configuration class
	// 这就是找Component的实现类
	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 {
		// 这个是重点parse有很多Component类这里用来
		parser.parse(candidates);
		/**
		 * 省略代码
		 */
	}
	while (!candidates.isEmpty());
	/**
	 * 省略代码
	 */
}
/**
 * 5.扫描Component和自动装配,这个也很重要,而且段代码有几个递归也是比较复杂
 * 也是希望大家能够自己debug进去看看这到底是如何递归的
 */
protected final SourceClass doProcessConfigurationClass(
			ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
			throws IOException {

		/**
		 * 省略代码
		 */
		// Process any @ComponentScan annotations
		// 这个为什么是数组呢?当你使用@ComponentScans(value = {@ComponentScan("com.example.test"), @ComponentScan("com.example.test1")})
		// 这里的长度就会变成3
		Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
				sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
		if (!componentScans.isEmpty() &&
				!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
			// 开始以启动类扫描,这就是为什么启动类永远在所有包的最外层,如果要扫描其他模块或者启动类以外的包就要@ScanComponent这个注解
			for (AnnotationAttributes componentScan : componentScans) {
				// The config class is annotated with @ComponentScan -> perform the scan immediately
				// 这里面就开始扫描doScan方法,只要是有@Component注解的都会把每个类的Definition放到scannedBeanDefinitions里面
				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)) {
						// 这里有事解析这个Bean,跟刚刚的parser.parse一样,只是一个是数组一个是单个Bean
						// 并且他会递归调用doProcessConfigurationClass()方法,并且重新执行一次获取看看这个类有没有@ComponentScan,并且继续扫描直至结束
						parse(bdCand.getBeanClassName(), holder.getBeanName());
					}
				}
			}
		}

		// Process any @Import annotations
		// 其实每一个parse方法都会走到这里,把每个类的注解都会去循环一次,直至没有注解位置,会把@Import注解的类全部加载出来,这就是自动装配的原理
		// 这就是为什么我其他jar包的类可以给Spring管理@Import就是一个重点,把这个类导入到BeanFactory里面
		processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

		/**
		 * 省略代码
		 */
		return null;
	}

创建Bean实例

/**
 * 创建bean实例,这里的方法过于复杂用文章非常难解释,笔者这里就把大致的思路说下
 * 1.getBean的时候先去createBean如果有就返回没有的话doCreateBean
 * 2.当doCreateBean的时候就会触发bean的生命周期的各个接口
 * 3.其实笔者发现一个东西,ApplicationContextAware并不算是bean生命周期的一环把,而是输入上下文的一环
 * 4.因为ApplicationContextAware其实是由添加了AnnotationConfigServletWebServerApplicationContext类所导致的
 * 5.创建bean的我会有下面的uml图让大家更能理解Bean是如何创建的
 */
public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		// 获取所有的BeanName
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
											((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				else {
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

关于ApplicationContext

实现ApplicationContextAware接口会调用setApplicationContext方法,而ApplicationContextAwareProcessor又是实现BeanPostProcessor,而ApplicationContextAwareProcessor又被Spring强制注册,所以说如果一个Bean实现ApplicationContextAware和BeanPostProcessor,在先初始化有关于BeanPostProcessor的Bean时候会创建这个Bean创建这个Bean的时候又会调用setApplicationContext方法调用完之后最后才会调用BeanPostProcessor实现的方法,其实听拗口的,所以最后还是希望自己能Debug一下

bean生命周期流程图

小结

当我重新重构这篇文章的时候,其实是因为我自己都读不懂之前的文章,希望这章大家可以看得懂。大家读不懂肯定是说明我的文采还不够好,也希望大家多多指出笔者的错误。
说到Spring其实在座的各位都是Spring工程师,老搬砖奴,但是大家肯定也因为忙没时间去研究整个Spring的流程。这里笔者帮大家都全部准备好了。

 

最后

最近我整理了整套《JAVA核心知识点总结》,说实话 ,作为一名Java程序员,不论你需不需要面试都应该好好看下这份资料。拿到手总是不亏的~我的不少粉丝也因此拿到腾讯字节快手等公司的Offer

Java进阶之路群,找管理员获取哦-!

以上是关于读完这章,你还敢说你不会SpringBoot源码?的主要内容,如果未能解决你的问题,请参考以下文章

看完你还敢说你懂JVM吗?

不懂这些SEO技巧,你还敢说你是前端?

看完这几个问题 你还敢说你懂电脑吗?

看了这篇文章,你还敢说你了解volatile关键字吗?

❤️ 教你零基础安装 Oracle 数据库,你敢说你还不会?⭐️

❤️ 教你零基础安装 Oracle 数据库,你敢说你还不会?⭐️