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); } }
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
上一篇
已是最后文章
下一篇
已是最新文章