SpringBoot源码学习(更新中)

(4) 2024-07-10 13:12

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
SpringBoot源码学习(更新中),希望能够帮助你!!!。

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

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

欢迎老司机指出

参考文章:

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

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

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

以下就是项目入口代码,很简单,由于是在慕课网上学习的,这里的报名就直接写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); } }



今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

上一篇

已是最后文章

下一篇

已是最新文章

发表回复