启动一个springboot环境
完成了必要的依赖之后,只需要按照如下代码操作,就可以启动springboot了。
常规写法:
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
另一种写法:效果一样
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication();
springApplication.run(args);
}
}
稍微看一下源码,不深入
按照上面常规写法,进入run( ... )方法后,大致上有2个步骤
1. 执行public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources)
构造器,源码注释如下:
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
System.out.println("---------------- SpringApplication ----------------");
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 设置Initializer, 在7里面会用到
// 通过类加载器从META-INFO/spring.factories里找出所有的ApplicationContextInitializer.class对应的值,设置到Initializers里
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
- 执行run( ... )方法,源码如下
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(); // 1. 1个listener启动,问题:这1个listener是干什么的
try {
// 2. 这里可以解释:java -jar xxx.jar --spring.profiles.active=dev,为什么用--开头
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 3. 从这里应该回去,准备环境的
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
// 4. 打印靴子吗?打印spring boot吗?
Banner printedBanner = printBanner(environment);
// 5. 生成哪种上下文,决定着是否会启动web容器
context = createApplicationContext();
// 6. 从spring.factories里获取信息,然后返回FailureAnalyzers对象
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
/* 7. 准备上下文
7.1 设置context的conversionService为ApplicationConversionService
7.2 调用Initializer的初始化方法,Initializer在SpringApplication构造函数里设置
7.3 通过EventPublishingRunListener调用contextPrepared,策略模式
7.4 直接把参数(applicationArguments, printedBanner)扔进spring容器(singletonObjects)里,applicationArguments对象里有 --spring.profiles.active=dev
7.5 sources就是yml文件里配置的spring.main.sources
7.6 加载spring.main.sources值的类
7.7 EventPublishingRunListener里的contextLoaded方法
*/
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 8. spring初始化,这里是spring framework的基础知识
refreshContext(context); // 进入SpringFramework 12大护法里
// 9. 该方法应该是个钩子,没有内容
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
// 10. EventPublishingRunListener里started方法
listeners.started(context);
// 11. 执行实现了CommandLineRunner,ApplicationRunner接口的类里的run方法
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
// 12. 处理异常
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
好啦,简单吧。。。
未完待续。。。。。。
网友评论