SpringBoot杂记

启动


入口

@SpringBootApplication
public class XlcqqApplication {
	public static void main(String[] args) {
		SpringApplication.run(XlcqqApplication.class, args);
	}
}

整个项目将从SpringApplication.run()这个关键方法启动,SpringApplication是引导SpringBoot启动的一个工具类,这个类提供的run()是一个关键方法,其中最重要的功能就是创建spring的context

创建SpringContext

run()源码片段如下

try {
			......
			context = createApplicationContext();
			......
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
			refreshContext(context);
			......
		}

可见就是调用了createApplicationContext()来创建context的,进入createApplicationContext方法:

Class<?> contextClass = this.applicationContextClass;
		if (contextClass == null) {
			try {
				switch (this.webApplicationType) {
				case SERVLET:
					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);
				}
			}

会发现SpringBoot将根据webApplicationType属性来创建对应的context实例,预定义的两个实例class为

	public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
			+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";


	public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
			+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";

至此,便知道SpringBoot启动Spring其实就只是根据当前环境,创建了AnnotationConfigServletWebServerApplicationContext或者AnnotationConfigReactiveWebServerApplicationContext二者之一来作为Spring的context。

加载Spring的Bean

在上面的run()方法中,创建了spring context之后,接着要加载bean,这是在第二步 prepareContext()中完成的。源码如下:

private void prepareContext(ConfigurableApplicationContext context,
			ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
			ApplicationArguments applicationArguments, Banner printedBanner) {
		context.setEnvironment(environment);
		...... //一系列准备工作
		load(context, sources.toArray(new Object[0]));
		listeners.contextLoaded(context);
	}

上面的方法中,最后用调用了load()这个方法,进入load()

protected void load(ApplicationContext context, Object[] sources) {
		if (logger.isDebugEnabled()) {
			logger.debug(
					"Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
		}
		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();
	}

这个方法中,创建了一个 BeanDefinitionLoader的实例loader,而这个loader,就是spring中用来加载bean的loader,从这里开始,后续也就是在执行spring原有的加载bean的一系列功能了。

小结:

对于以上SpringBoot启动的三步总结如下:

  1. 首先SpringBoot的入口main函数中,调用了SpringApplication.run()方法,这个方法主要用途是创建一个spring context实例
  2. 在run()中,将根据当前项目环境,创建一个对应的spring context
  3. 创建了srping context之后,会委托spring原有的BeanDefinitionLoader来加载bean

以上是SpringBoot启动的主要步骤,但是非常粗略,其中还涉及到非常多的事情,例如一个starter是如何做到自动配置启动的,Spring WEB启动的时候是如何自动启动tomcat的等等。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值