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);
   }
}



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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 向自增长表中插入数据可使用default填充自增长字段

    向自增长表中插入数据可使用default填充自增长字段向自增长表中插入数据可使用default填充自增长字段

  • springboot项目启动原理_转膜原理

    springboot项目启动原理_转膜原理1.总览上图为SpringBoot启动结构图,我们发现启动流程主要分为三个部分,第一部分进行SpringApplication的初始化模块,配置一些基本的环境变量、资源、构造器、监听器,第二部分实现了应用具体的启动方案,包括启动流程的监听模块、加载配置环境模块、及核心的创建上下文环境模块,第三部分是自动化配置模块,该模块作为springboot自动配置核心2.常用注解解释任何一个标注了@Bean的方法,其返回值将作为一个bean定义注册到Spring的IoC容器,方法名将默认成该bean定义的id.

  • SDK封装_java封装类

    SDK封装_java封装类本文主要讲解java封装jar包的过程,一个简单的demo,方便大家入手学习打包jar包。转载地址:https://www.cnblogs.com/shirui/p/5270969.html准备材料: 1.java文件:      Helloworld.java packagecom.ray;publicclassHelloWorld{publicstaticvoidma…

    2022年10月21日
  • 模电基础知识点小结[通俗易懂]

    模电基础知识点小结[通俗易懂]第一章常用半导体器件在本征半导体中加入三价元素可形成P型半导体。(五价磷元素形成N型)当PN结加正向电压时,空间电荷区将(变窄)。PN结的单向导电性:在PN结两端加正向电压时,内电场被削弱,空间电荷区变窄,有利于多子扩散,不利于少子漂移,PN结处于导通状态;当在PN结两端加反向电压时,内电场增强,空间电荷区变宽,有利于少子漂移,不利于多子扩散,PN结处于反向截止状态。当二极管外加正向电压增大时,其动态电阻增大。(×)要使稳压管的稳压,其工作区为(反向击穿区)。稳压管与普通二极管的

  • vs2013产品密钥(所有版本)「建议收藏」

    vs2013产品密钥(所有版本)「建议收藏」https://blog.csdn.net/asd051377305/article/details/80714859

  • hashmap的底层实现原理_hashtable底层数据结构

    hashmap的底层实现原理_hashtable底层数据结构一:HashMap底层实现原理解析我们常见的有数据结构有三种结构:1、数组结构2、链表结构3、哈希表结构下面我们来看看各自的数据结构的特点:1、数组结构:存储区间连续、内存占用严重、空间复杂度大优点:随机读取和修改效率高,原因是数组是连续的(随机访问性强,查找速度快)缺点:插入和删除数据效率低,因插入数据,这个位置后面的数据在内存中都要往后移动,且大小固定不易动态扩展。2、链表结构:存储区间离散、占用内存宽松、空间复杂度小优点:插入删除速度快,内存利用率高,没有固定大小,扩展灵活

发表回复

您的电子邮箱地址不会被公开。

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