SpringBoot源码学习(更新中)

SpringBoot源码学习(更新中)SpringBoot源码学习(更新中)

大家好,又见面了,我是你们的朋友全栈君。

最近在项目中运用了Springboot,简单的学习了简单的使用,于是想去看看源码是如何实现的。

自己也是第一次尝试看源码,结合了网上的东西和自己的理解,在博客里写点东西,做做积累, 如果其中哪些地方解释有问题,

欢迎老司机指出

参考文章:

1.https://my.oschina.net/u/3081965/blog/916126

2.http://www.cfanz.cn/index.php?c=article&a=read&id=307782

首先不知道从哪里入手,于是我从项目的启动入口开始。

以下就是项目入口代码,很简单,由于是在慕课网上学习的,这里的报名就直接写imooc了(这个为对应springboot的学习地址:http://www.imooc.com/learn/767)

这边的spring-boot版本为1.4.7

package com.imooc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GirlApplication {

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

@SpringBootApplication 注解暂时不讲,先从下面这个方法开始讲起
SpringApplication.run(GirlApplication.class, args);

点击进去可以看到

	/**
	 * Static helper that can be used to run a {@link SpringApplication} from the
	 * specified source using default settings.
	 * @param source the source to load
	 * @param args the application arguments (usually passed from a Java main method)
	 * @return the running {@link ApplicationContext}
	 */
	public static ConfigurableApplicationContext run(Object source, String... args) {
   
   
 //第一次进入到达这里
		return run(new Object[] { source }, args);
	}

	/**
	 * Static helper that can be used to run a {@link SpringApplication} from the
	 * specified sources using default settings and user supplied arguments.
	 * @param sources the sources to load
	 * @param args the application arguments (usually passed from a Java main method)
	 * @return the running {@link ApplicationContext}
	 */
	public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
   
   
 //上面方法后进入这里
		return new SpringApplication(sources).run(args);
	}

首先为第一步,第一步调用第二部的方法,这里主要看下第二步。

第二步这边分为两个步骤去看,第一个步骤为调用SpringApplication类的构造方法创建对象,第二步为调用创建对象的run方法,这里以这两个步骤进行解读。

构建对象:
	/**
	 * Create a new {@link SpringApplication} instance. The application context will load
	 * beans from the specified sources (see {@link SpringApplication class-level}
	 * documentation for details. The instance can be customized before calling
	 * {@link #run(String...)}.
	 * @param sources the bean sources
	 * @see #run(Object, String[])
	 * @see #SpringApplication(ResourceLoader, Object...)
	 */
	public SpringApplication(Object... sources) {
   
   
 //调用初始化方法
		initialize(sources);
	}

	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void initialize(Object[] sources) {
   
   
 //将对象资源存放到sources这个linkedSet下,这里的sources就是上诉的com.imooc.GirlController对象
		if (sources != null && sources.length > 0) {
			this.sources.addAll(Arrays.asList(sources));
		}
 //这里暂时没有看懂,从字面上来看,是判断是否有web环境
		this.webEnvironment = deduceWebEnvironment();
 //实例化Initializer,initializers成员变量,是一个ApplicationContextInitializer类型对象的集合。 
 //顾名思义,ApplicationContextInitializer是一个可以用来初始化ApplicationContext的接口。
 //初始化ApplicationContext的Initializer程序
 //boot包下的META-INF/spring.factories
 0 = "org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer"
 1 = "org.springframework.boot.context.ContextIdApplicationContextInitializer"
 2 = "org.springframework.boot.context.config.DelegatingApplicationContextInitializer"
 3 = "org.springframework.boot.context.web.ServerPortInfoApplicationContextInitializer"
 //autoconfigure下的META-INF/spring.factories
 4 = "org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer"
 5 = "org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer"
		setInitializers((Collection) getSpringFactoriesInstances(
				ApplicationContextInitializer.class));
 //实例化监听器
 //初始化 ApplicationListener  boot下9个,autoconfigure一个
 //0 = "org.springframework.boot.ClearCachesApplicationListener"
 //1 = "org.springframework.boot.builder.ParentContextCloserApplicationListener"

//2 = "org.springframework.boot.context.FileEncodingApplicationListener"
//3 = "org.springframework.boot.context.config.AnsiOutputApplicationListener"
//4 = "org.springframework.boot.context.config.ConfigFileApplicationListener"
//5 = "org.springframework.boot.context.config.DelegatingApplicationListener"
//6 = "org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener"
//7 = "org.springframework.boot.logging.ClasspathLoggingApplicationListener"
//8 = "org.springframework.boot.logging.LoggingApplicationListener"
//9 = "org.springframework.boot.autoconfigure.BackgroundPreinitializer"setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

 //找出main方法的全类名并返回其实例并设置到SpringApplication的this.mainApplicationClass完成初始化
		this.mainApplicationClass = deduceMainApplicationClass();
	}

这里附上deduceWebEnvironment()方法的实现,其中WEB_ENVIRONMENT_CLASSES的值为


 private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet",
			"org.springframework.web.context.ConfigurableWebApplicationContext" };

 private boolean deduceWebEnvironment() {
		for (String className : WEB_ENVIRONMENT_CLASSES) {
			if (!ClassUtils.isPresent(className, null)) {
				return false;
			}
		}
		return true;
	}
上面SpringApplication的初始化动作已经做完了,然后看下run方法里做了哪些操作。
public ConfigurableApplicationContext run(String... args) {
   
   
   
 //StopWatch是一个监视器,主要是用来记录程序的运行时间,这里是用来记录程序启动所需要的时间
   StopWatch stopWatch = new StopWatch();
   stopWatch.start();
   ConfigurableApplicationContext context = null;
   FailureAnalyzers analyzers = null;
   configureHeadlessProperty();
   SpringApplicationRunListeners listeners = getRunListeners(args);
   listeners.started();
   try {
      ApplicationArguments applicationArguments = new DefaultApplicationArguments(
            args);
      ConfigurableEnvironment environment = prepareEnvironment(listeners,
            applicationArguments);
      Banner printedBanner = printBanner(environment);
      context = createApplicationContext();
      analyzers = new FailureAnalyzers(context);
      prepareContext(context, environment, listeners, applicationArguments,
            printedBanner);
      refreshContext(context);
      afterRefresh(context, applicationArguments);
      listeners.finished(context, null);
      stopWatch.stop();
      if (this.logStartupInfo) {
         new StartupInfoLogger(this.mainApplicationClass)
               .logStarted(getApplicationLog(), stopWatch);
      }
      return context;
   }
   catch (Throwable ex) {
      handleRunFailure(context, listeners, analyzers, ex);
      throw new IllegalStateException(ex);
   }
}



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/132201.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 一个线程有几个threadlocal_thread线程

    一个线程有几个threadlocal_thread线程基本概念程序是指令的有序集合,其本身没有任何运行的含义,是一个静态的概念。而进程是程序在处理机上的一次执行过程,它是一个动态的概念。进程是由程序、数据和进程控制块三部分组成的。进程是操作系统资源分配的基本单位,而线程是任务调度和执行的基本单位。每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己…

    2025年8月8日
    4
  • c语言定时器实验程序,C语言定时器实验.doc[通俗易懂]

    c语言定时器实验程序,C语言定时器实验.doc[通俗易懂]C语言定时器实验实验三C语言定时器实验一、实验目的1.进一步熟悉DSP的中断机制2.在掌握中断服务程序编写的基础上进一步熟悉定时器的运用3.进一步掌握如何编写DSP中断服务子程序二、实验设备1.具有USB接口的PC机一台2.USB仿真器一台3.ARM/DSP/FPGA实验箱一台三、实验原理本实验是在我们基本上掌握DSP中断机制的基础上,进一步学习如何在DSP内部实现定时器的正确操作以及定时器中…

    2022年7月26日
    7
  • mac用什么软件录屏_macbookair录屏快捷键

    mac用什么软件录屏_macbookair录屏快捷键录屏软件哪个好?你是否遇到过需要记录手机或者电脑屏幕的时候,就像是打着游戏、看着剧,突然想要记录此时屏幕上的内容。其实很多的场景都可以使用录屏软件来记录屏幕上的内容,像是工作、学习、娱乐上的内容。那有什么好用的录屏软件和方法,一起来看看下面有关的方法介绍!分享录屏软件一、手机专业录制软件如果你在手机上查看视频的话,除了使用手机中的屏幕录制方法。还可以使用专业的录屏软件。如借助手机中的“嗨格式录屏大…

    2022年9月15日
    3
  • 国内数据集网站_数据网站

    国内数据集网站_数据网站如果你是一个初学者,你每完成一个新项目后自身能力都会有极大的提高,如果你是一个有经验的数据科学专家,你已经知道这里所蕴含的价值。 本文将为您提供一个网站/资源列表,从中你可以使用数据来完成你自己的数据项目,甚至创造你自己的产品。一.如何使用这些资源?如何使用这些数据源是没有限制的,应用和使用只受到您的创造力和实际应用。使用它们最简单的方法是进行数据项目并在网站上发布它们。这不仅能提高你的数…

    2022年10月16日
    3
  • eplan破解后又出现激活码(注册激活)

    (eplan破解后又出现激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~HCIQ56F36O-eyJsaWNlbnNlSWQiOi…

    2022年4月1日
    654
  • 改变maven打包路径_Maven打包技巧「建议收藏」

    改变maven打包路径_Maven打包技巧「建议收藏」“打包“这个词听起来比较土,比较正式的说法应该是”构建项目软件包“,具体说就是将项目中的各种文件,比如源代码、编译生成的字节码、配置文件、文档,按照规范的格式生成归档,最常见的当然就是JAR包和WAR包了,复杂点的例子是,它有自定义的格式,方便用户直接解压后就在命令行使用。作为一款”打包工具“,Maven自然有义务帮助用户创建各种各样的包,规范的JAR包和WAR包自然不再话下,略微复杂的自定义打包…

    2022年5月30日
    37

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号