SpringBoot的启动类为**Application,一注解@SpringBootApplication注明
@SpringBootApplication
public class cmsApplication{
public static void main(String[] args){
SpringApplication.run(cmsApplication.class, args);
}
}
SpringBootApplication注解是@Configration,@EnableAutoConfigration,@ComponentScan三个注解集成的,分别表示SpringBean的配置Bean,开启自动配置Spring的上下文,组件扫描的路径,这也是为什么*application.java需要放在根路径的原因,这样@ComponentScan扫描的才是整个项目
SpringApplication这个类
public static ConfigrationContext run(Object source, String... args){
return run(new Object[]{source}, args);
}
public static ConfigrationContext run (Object[] sources, String... args){
return (new SpringApplication(sources)).run(args);//sources为具体的cmsApplication.calss类
}
抽出其中两个直接的调用的run方法,可以看出静态方法SpringApplication.run最终创建了一个SpringApplication,并运行其中的run方法
查看构造方法
public SpringApplication(Object... sources){
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLinePeopleties = true;
this.handless = true;
this.registerShutdownHook = true;
this.additionalProfiles = new HashSet();
this.initialize(sources);
}
构造方法设置了基础调用initialize方法进行初始化
private void initialize(Object... sources){
if(sources != null && sources.legth > 0){
this.sources.addAll(Arrays.asList(sources));
}
this.webEnvironment = this.deduceWebEnvironment();
this.setInitializer(this.getSpringFactoriesInstances(ApplicationContextInitialize.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
初始化主要做了几步,
1.将source放入SpringApplication的source属性中管理,source是一个LinkedHashSet(),这意味着我们可以同时创建多个自定义不重复的Application,但是目前只有一个
2.判断是否是web程序(javax.servlet.Servlet和org.Springframework.web.context.ConfigurableWebApplicationContext都必须在类加载器中存在,并设置到WebEnvironment属性中)
3.从spring.factories中找出ApplicationContextInitializeer并设置初始化器initializers
4.从spring.factories中找出ApplicationListener,并实例化后设置到SpringApplication的监听器listener属性中。这个过程就是找出所有的应用程序时间监听器。
5.找出的main方法的类(这里是CmsApplication),并返回Class对象
SpringApplication构造和初始化完成后,运行run方法
public ConfigurableApplicationContext run(String... args){
StopWatch stopWatch = new StopWatch();//构造一个任务执行观察器
stopWatch.start();//开始执行,记录开始时间
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
this.configureHeadlessProperty();
//获取SpringApplicationRunListenners,内部只有一个EventPublishingRunListener
SpringApplicationRunListeners listeners = this.getRunListeners(args);
//封装成SpringEvent事件后,广播出去给SpringApplication中的Listener监听,启动监听机制,
listeners.starting();
try{
//构造一个应用程序参数持有类
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//加载配置环境
ConfigurableEnvironment encvironment = this.prepareEnvironment(listeners,applicationArgument);
Banner printeBanner = this.printBanner(environment);
//创建Spring容器(使用BeanUtils.instentiate)
context = this.createApplication();
//若容器创建失败,分析失败原因
new FailureAnalyzers(context);
//设置容器配置环境,监听等
this.prepaerContext(context,environment,listeners,applicationArguments,printedBanner);
//刷新容器
this.refreshContext(context);
this.afferRefresh(context, applicationArguments);
//广播出ApplicationReadyEvent时间给相应的监听机制
}
}