springboot源码分析

依赖管理

spring-boot-starter-parent如何管理依赖版本

每一个springboot项目都有一个依赖管理
在这里插入图片描述
点版本号查看,发现底层有一个父依赖spring-boot-dependencies,然后继续点击spring-boot-dependencies查看源码,发下如下
在这里插入图片描述
在这里插入图片描述

项目运行依赖的jar包的管理

例如,如果你想给springboot添加web功能,只需引入spring-boot-starter-web
在这里插入图片描述
那么,springboot又是如何做到只引入一个依赖就能集成所有的依赖,我们进入spring-boot-starter-web查看源码,
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

自动装配

概念

在这里插入图片描述

如何进行自动装配,哪些组件进行了自动装配

先查看Springboot的启动类
在这里插入图片描述
核心注解@SpringBootApplication底层源码如下
在这里插入图片描述
在这里插入图片描述

@SpringBootConfiguration

在这里插入图片描述
在这里插入图片描述

@EnableAutoConfiguration

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下边,我们分别来看这两个注解

@AutoConfigurationPackage

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过Debug模式可以看到,在Registrar类中的registerBeanDefinitions方法中调用register方法(此方法属于AutoConfigurationPackages),传入的实参
new PackageImports(metadata).getPackageNames().toArray(new String[0])的值为com.mycode.springbootdemo,也就是说,@AutoConfigurationPackage注解的主要作用就是将启动类所在的包以及子包下的所有组件扫描进I
在这里插入图片描述
在这里插入图片描述

@Import(AutoConfigurationImportSelector.class)

在这里插入图片描述
我们先看AutoConfigurationImportSelector这个类源码,里边有个方法selectImports告诉springboot都需要导入哪些组件
在这里插入图片描述
通过点击getAutoConfigurationEntry方法里边的getCandidateConfigurations方法
在这里插入图片描述
getCandidateConfigurations方法里边有一个重要的方法loadFactoryNames,这个方法是让SpringFactoryLoader去加载一些组件名称
在这里插入图片描述
继续点开loadFactoryNames,点开里边的重载方法loadSpringFactories,可以看到会去读取一个spring.factories文件FACTORIES_RESOURCE_LOCATION
在这里插入图片描述
继续查看文件,可以看到
在这里插入图片描述
这个是去加载外部文件,而这个文件是在
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

@ComponentScan

在这里插入图片描述
在这里插入图片描述

总结

在这里插入图片描述
在这里插入图片描述

执行原理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

springapplication实例的初始化创建

查看springapplication实例化的核心代码,如下
在这里插入图片描述
在这里插入图片描述
1 this.webApplicationType = WebApplicationType.deduceFromClasspath();
在这里插入图片描述
2 setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));

在这里插入图片描述
3 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
在这里插入图片描述
4 this.mainApplicationClass = deduceMainApplicationClass();
在这里插入图片描述

项目的初始化启动

在这里插入图片描述

	/**
	 * Run the Spring application, creating and refreshing a new
	 * {@link ApplicationContext}.
	 * @param args the application arguments (usually passed from a Java main method)
	 * @return a running {@link ApplicationContext}
	 */
	public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
		SpringApplicationRunListeners listeners = getRunListeners(args);
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
			configureIgnoreBeanInfo(environment);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
			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;
	}

从源码中可以看出,项目初始化启动大致可以分为以下几类
第一步:获取并启动监听器
getRunListeners(args)和starting主要用户获取SpringApplication实例化过程中初始化的SpringApplicationRunListener并且运行

第二步:根据SpringApplicationRunListeners以及参数来准备环境
prepareEnvironment(listeners, applicationArguments)方法主要对项目运行环境进行预设值;同时通过configureIgnoreBeanInfo(environment)方法排除掉一些不需要的运行环境

第三步:创建spring容器
context = createApplicationContext();
在这里插入图片描述
第四步:spring容器前置处理
prepareContext(context, environment, listeners, applicationArguments, printedBanner) 这一步主要是容器刷新之前的准备动作,设置容器环境,包括各种变量等等,其中包含一步非常关键的操作:将启动类注入容器,为后续开启自动化配置奠定基础

第五步:刷新容器
refreshContext(context);
在这里插入图片描述

第六步:spring容器后置处理
afterRefresh(context, applicationArguments);
在这里插入图片描述
第七步:发出结束执行的事件
listeners.started(context);
在这里插入图片描述
第八步:执行Runners

在这里插入图片描述
第九步:发布应用上下文就绪事件
listeners.running(context);
如果在前面的一切初始化启动都没有问题,使用运行监听器SpringApplicationRunListener持续运行配置好的应用上线文applicationcontext

流程图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值