Springboot 原理篇(一)
程序员文章站
2024-03-24 17:41:46
...
相信Springboot使用的越来越广泛了,约定大于配置,对于开发者使用确实是方便了,但是Springboot底层的原理清楚吗?下
面从源码一步一步来揭秘Springboot
从Springboot入口Main函数分析
public static void main(String[] args) {
SpringApplication.run(XlbstudyApplication.class, args);
}
···debug···
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
return new SpringApplication(sources).run(args);
}
我们可以看到 new SpringApplication(sources).run(args)
重点:第一步 new SpringApplication
private void initialize(Object[] sources) {
if (sources != null && sources.length > 0) {
//保存配置类
this.sources.addAll(Arrays.asList(sources));
}
//判断是否是Web环境
this.webEnvironment = deduceWebEnvironment();
//重点 主要内容:从 META-INF/spring.factories 加载Initializers
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//重点 主要内容:从 META-INF/spring.factories 加载Listeners
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//选择 有main函数入口的配置类
this.mainApplicationClass = deduceMainApplicationClass();
}
我们随便打开一个spring.factories文件看看
# Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer
重点: 第二步 run
run方法的代码如下
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch(); //这个就不解释了
stopWatch.start();
//定义一个ioc容器
ConfigurableApplicationContext context = null;
//定义一个失败分析器,用于异常分析的
FailureAnalyzers analyzers = null;
//点进去可以发现是配置awt的 对我们正常的开发web应用没什么卵用
configureHeadlessProperty();
//重点 获取listener ,我们从第一步可以看到加载了listener
SpringApplicationRunListeners listeners = getRunListeners(args);
//重点 回调 listenr的start方法
listeners.starting();
try {
//包装web容器参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
//重点 准备环境变量 分析里面代码:listeners.environmentPrepared(environment);
//回掉 listeners的 environmentPrepared 方法
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
//打印Banner 没卵用
Banner printedBanner = printBanner(environment);
//初始化 ioc容器
context = createApplicationContext();
//初始化
analyzers = new FailureAnalyzers(context);
/*重点 准备上下文容器:
* 回调初始化器
* initializer.initialize(context);
* 回调 listener
* listeners.contextPrepared(context);
*/
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
/*
* 重中之重 spring ioc容器初始化,加载Spring bean 这个我们单独抽出来在讲重点会讲
* BeanPostProcessor后置处理器,其实xxAware ,@Autoword... 原理就是BeanPostProcessor
* 后面我们在讲
*/
refreshContext(context);
/*
* ioc容器初始化完成后 ,回调ApplicationRunner CommandLineRunner的run方法
* callRunner((ApplicationRunner ) runner, args);
* callRunner((CommandLineRunner) runner, args);
*/
afterRefresh(context, applicationArguments);
/*
* 回调listener 的 finished方法
*/
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);
}
}
总结:从上面的代码我们可以看到 Springboot为我们提供了4个组件 供我们扩展使用
ApplicationContextInitializer
ApplicationListener
ApplicationRunner
CommandLineRunner
至于什么情况下会回调上面的组件 上诉源码写的很清楚了。但是核心的原理关键还是在refreshContext
下面章节重点会讲解refreshContext,通过refreshContext源码可以知道Spring 扩展的原理,springboot 各种注解如
何实现,以及Springboot-start如何实现的
转载于:https://my.oschina.net/xliangbo/blog/2253903
上一篇: Maven安装配置
下一篇: Mac 使用 homebrew 教程