Sprinboot启动流程源码简析,每行都有功能注释

发布时间:2024年01月04日

实际上, 要谈Springboot启动流程, 我们不如说 Springboot 是如何实现IOC和AOP 这两大功能的。说完这两部分功能的实现,Springboot也就启动完毕了。

IOC

众所周知,IOC 是依赖反转,是一种设计原则,将类的创建和使用解耦,由外部容器来控制程序的流程,那么首先就要有个容器。

容器 Beanfactory 和 ApplicationContext的区别

首先我们看下Application的默认实现:

// 简化源码 在SpringApplication类中
	protected ConfigurableApplicationContext createApplicationContext() {
		Class<?> contextClass = this.applicationContextClass;
		return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClassClass.forName("org.springframework.context.annotation"
							+ ".AnnotationConfigApplicationContext"));
	}

默认创建的ApplicationContext对象是AnnotationConfigApplicationContext类型,而它的父类为GenericApplicationContext。

public class GenericApplicationContext{
// 有一个属性为BeanFactory
	private final DefaultListableBeanFactory beanFactory;
}

这边可以清晰的看到, ApplicationContext中其实是包含Beanfactory的,那么我们可以编码层面理解为一个组合关系。
逻辑层面, 我们可以理解为:ApplicationContext是包含Beanfactory,和其他更多功能的对外组件,而BeanFactory只是一个和创建Bean对象有关的, 单一功能的对内组件。

SpringApplication.run()

	public ConfigurableApplicationContext run(String... args) {
		try {
			// 准备环境:将 profile application 配置文件 配置的资源到environment;
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
			// 创建应用上下文(上面已经讲过,我们只需要知道是根据web类型,推断出一个ApplicationContext就行)
			context = createApplicationContext();
			// 将主类 构造成BeanDefinition 注册到 applicationContext中
			prepareContext(context, environment, listeners, applicationArguments, printedBanner);
			// 1. 构造BeanDefinition,2.实例化Bean,3.判断是否要动态代理 4. 执行类中声明周期相关的方法,比如@PointCut标注的方法
			refreshContext(context);
			afterRefresh(context, applicationArguments);
		}
		return context;
	}

其他的方法还算简单,流程清晰。默认的ApplicationContext是AnnotationConfigApplicationContext。那我们重点从AnnotationConfigApplicationContext出发,看下refreshContext方法。

AnnotationConfigApplicationContext.refreshContext()

上面我们提到,在refreshContext方法中,我们实现了Config–>BeanDefinition–>Bean–>InvokeInitMethod–>Proxy的整个步骤,这边只截取最核心的代码行来介绍。

代码行格式说明:方法名()[实现类]{方法内部截取} 。为简明,方法参数部分省略。

public void refresh()  {
		try {
			// - 默认实现为AnnotationConfigApplicationContext。这个方法是空,不执行
			// - 如果实现为AnnotationConfigServletWebApplicationContext等,有执行。
			// 		其中方法内比较重要的调用为Scan(packages).功能也是将BeanDefinition读取出来
			postProcessBeanFactory(beanFactory);

			// 执行后置方法。整个方法的重点功能:将@Component转换成BeanDefinition
			invokeBeanFactoryPostProcessors()[AnnotationConfigApplicationContext]{
				// AbstractApplicationContext 执行调用后置方法
				PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors()[AbstractApplicationContext]{
					invokeBeanFactoryPostProcessors()[PostProcessorRegistrationDelegate]{
							// 后置处理器是个列表, 我们重点关注 BeanFactoryPostProcessor的实现类:ConfigurationClassPostProcessor
						for (BeanFactoryPostProcessor postProcessor : postProcessors) {
							postProcessor.postProcessBeanFactory()[ConfigurationClassPostProcessor](){
								// 因为主类有注解@SpringApplication注解,而这个复合注解,同样将主类标注为一个Config,所以这里ConfigurationClassPostProcessor同样会处理到主类
								processConfigBeanDefinitions()[ConfigurationClassPostProcessor]{
										// 过程中,这里的candidates其实只有主类一个对象。parse方法就是读取主类目录下的其他component信息
									parser.parse(candidates);
									// 这里已经能读取到所有的component
									Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
									// 将componentInfo解析为BeanDefinition
									this.reader.loadBeanDefinitions(configClasses );
								};
							}
						}
					}
				}

			};
			// 源码注释:Instantiate all remaining (non-lazy-init) singletons.(实例化所有剩余非懒加载的单例类)
			finishBeanFactoryInitialization()[AbstractApplicationContext]{
				// Instantiate all remaining (non-lazy-init) singletons.
				beanFactory.preInstantiateSingletons()[DefaultListableBeanFactory]{
					getBean(beanName)[AbstractBeanFactory]{
						doGetBean()[AbstractBeanFactory]{
							return createBean()[AbstractAutowireCapableBeanFactory]{
								// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
								// 源码注释:给个机会返回代理类 这边主要是配置类相关,具体可以看源码的判断条件,实际上,我们业务的BusinessImpl走在下面的doCreateBean()
								Object bean = resolveBeforeInstantiation()[AbstractAutowireCapableBeanFactory]{
									bean = applyBeanPostProcessorsBeforeInstantiation();
									if (bean != null) {
										// 再后置处理器中, 创建代理
										bean = applyBeanPostProcessorsAfterInitialization();
									}
								};
								if (bean != null) {
									return bean;
								}
								Object beanInstance = doCreateBean()[AbstractAutowireCapableBeanFactory]{
									// 反射执行无参构造,实例化对象
									instanceWrapper = createBeanInstance();
									// 根据BeanDefinition填充属性
									populateBean();
									// 执行bean生命周期函数,比如实现A接口的,还有@PointCut注解的方法执行
									exposedObject = initializeBean()[AbstractAutowireCapableBeanFactory]{
										invokeAwareMethods(beanName, bean);
										invokeInitMethods(beanName, wrappedBean, mbd);
										// bean后置处理器
										wrappedBean = applyBeanPostProcessorsAfterInitialization()[AbstractAutowireCapableBeanFactory]{
												// 重点关注AbstractAutoProxyCreator。这个是实现动态代理功能的
											Object current = processor.postProcessAfterInitialization()[AbstractAutoProxyCreator]{
												return wrapIfNecessary()[AbstractAutoProxyCreator]{
													Object proxy = createProxy();
												};
											};
										};
									};
								};
								return beanInstance;
							};
						}
						
					};
				};
			};
		}
	}

结语:

整个源码阅读,大概花费了两个下午的时间,我这边也只是挑选了自己源码阅读过程中,觉得重要的部分,事实上并未能完全写明所有判断和功能。大家可以参照阅读。

文章来源:https://blog.csdn.net/qq_14853889/article/details/135389526
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。