springboot框架学习积累—SpringBoot的run方法
1.主启动类中SpringApplication.run()方法是如何启动SpringBoot项目的
public static ConfigurableApplicationContext run ( Class< ? > primarySource, String. . . args) {
return run ( new Class < ? > [ ] { primarySource } , args) ;
}
重载的run方法
public static ConfigurableApplicationContext run ( Class< ? > [ ] primarySources, String[ ] args) {
return new SpringApplication ( primarySources) . run ( args) ;
}
2.查看 实例化SpringApplication对象
public SpringApplication ( Class< ? > . . . primarySources) {
this ( null, primarySources) ;
}
查看 this,也是查看实例化SpringApplication都做了哪些事
public SpringApplication ( ResourceLoader resourceLoader, Class< ? > . . . primarySources) {
this . sources = new LinkedHashSet ( ) ;
this . bannerMode = Mode. CONSOLE;
this . logStartupInfo = true ;
this . addCommandLineProperties = true ;
this . addConversionService = true ;
this . headless = true ;
this . registerShutdownHook = true ;
this . additionalProfiles = new HashSet ( ) ;
this . isCustomEnvironment = false ;
this . resourceLoader = resourceLoader;
Assert. notNull ( primarySources, "PrimarySources must not be null" ) ;
this . primarySources = new LinkedHashSet < > ( Arrays. asList ( primarySources) ) ;
this . webApplicationType = WebApplicationType. deduceFromClasspath ( ) ;
setInitializers ( ( Collection) getSpringFactoriesInstances ( ApplicationContextInitializer. class ) ) ;
setListeners ( ( Collection) getSpringFactoriesInstances ( ApplicationListener. class ) ) ;
this . mainApplicationClass = deduceMainApplicationClass ( ) ;
}
查看 deduceFromClasspath方法,是如何判断 Web 应用类型的
static WebApplicationType deduceFromClasspath ( ) {
if ( ClassUtils. isPresent ( WEBFLUX_INDICATOR_CLASS, null)
&& ! ClassUtils. isPresent ( WEBMVC_INDICATOR_CLASS, null)
&& ! ClassUtils. isPresent ( JERSEY_INDICATOR_CLASS, null) ) {
return WebApplicationType. REACTIVE;
}
for ( String className : SERVLET_INDICATOR_CLASSES) {
if ( ! ClassUtils. isPresent ( className, null) ) {
return WebApplicationType. NONE;
}
}
return WebApplicationType. SERVLET;
}
查看 getSpringFactoriesInstances方法,查看都设置了哪些初始化器
private < T> Collection< T> getSpringFactoriesInstances ( Class< T> type) {
return getSpringFactoriesInstances ( type, new Class < ? > [ ] { } ) ;
}
查看重载的 getSpringFactoriesInstances方法
private < T> Collection< T> getSpringFactoriesInstances ( Class< T> type,
Class< ? > [ ] parameterTypes, Object. . . args) {
ClassLoader classLoader = getClassLoader ( ) ;
Set< String> names = new LinkedHashSet < > ( SpringFactoriesLoader. loadFactoryNames ( type, classLoader) ) ;
List< T> instances = createSpringFactoriesInstances ( type, parameterTypes, classLoader, args, names) ;
AnnotationAwareOrderComparator. sort ( instances) ;
return instances;
}
3.调用run方法
查看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 ( ) ;
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments ( args) ;
ConfigurableEnvironment environment = prepareEnvironment ( listeners, applicationArguments) ;
configureIgnoreBeanInfo ( environment) ;
Banner printedBanner = printBanner ( environment) ;
context = createApplicationContext ( ) ;
exceptionReporters = getSpringFactoriesInstances (
SpringBootExceptionReporter. class ,
new Class [ ] { ConfigurableApplicationContext. class } , context) ;
prepareContext ( context, environment, listeners, applicationArguments,
printedBanner) ;
refreshContext ( context) ;
afterRefresh ( context, applicationArguments) ;
stopWatch. stop ( ) ;
if ( this . logStartupInfo) {
new StartupInfoLogger ( this . mainApplicationClass) . logStarted ( getApplicationLog ( ) , stopWatch) ;
}
listeners. started ( context) ;
callRunners ( context, applicationArguments) ;
} catch ( Throwable ex) {
handleRunFailure ( context, ex, exceptionReporters, listeners) ;
throw new IllegalStateException ( ex) ;
}
try {
listeners. running ( context) ;
} catch ( Throwable ex) {
handleRunFailure ( context, ex, exceptionReporters, null) ;
throw new IllegalStateException ( ex) ;
}
return context;
}
查看getRunListeners方法
private SpringApplicationRunListeners getRunListeners ( String[ ] args) {
Class< ? > [ ] types = new Class < ? > [ ] { SpringApplication. class , String[ ] . class } ;
return new SpringApplicationRunListeners ( logger, getSpringFactoriesInstances (
SpringApplicationRunListener. class , types, this , args) ) ;
}
查看prepareEnvironment方法
private ConfigurableEnvironment prepareEnvironment ( SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
ConfigurableEnvironment environment = getOrCreateEnvironment ( ) ;
configureEnvironment ( environment, applicationArguments. getSourceArgs ( ) ) ;
listeners. environmentPrepared ( environment) ;
bindToSpringApplication ( environment) ;
if ( ! this . isCustomEnvironment) {
environment = new EnvironmentConverter ( getClassLoader ( ) ) . convertEnvironmentIfNecessary ( environment, deduceEnvironmentClass ( ) ) ;
}
ConfigurationPropertySources. attach ( environment) ;
return environment;
}
查看createApplicationContext方法
protected ConfigurableApplicationContext createApplicationContext ( ) {
Class< ? > contextClass = this . applicationContextClass;
if ( contextClass == null) {
try {
switch ( this . webApplicationType) {
case SERVLET:
contextClass = Class. forName ( DEFAULT_SERVLET_WEB_CONTEXT_CLASS) ;
break ;
case REACTIVE:
contextClass = Class. forName ( DEFAULT_REACTIVE_WEB_CONTEXT_CLASS) ;
break ;
default :
contextClass = Class. forName ( DEFAULT_CONTEXT_CLASS) ;
}
} catch ( ClassNotFoundException ex) {
throw new IllegalStateException ( "Unable create a default ApplicationContext, " + "please specify an ApplicationContextClass" , ex) ;
}
}
return ( ConfigurableApplicationContext) BeanUtils. instantiateClass ( contextClass) ;
}
查看prepareContext方法:Spring容器前置处理
private void prepareContext ( ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
context. setEnvironment ( environment) ;
postProcessApplicationContext ( context) ;
applyInitializers ( context) ;
listeners. contextPrepared ( context) ;
if ( this . logStartupInfo) {
logStartupInfo ( context. getParent ( ) == null) ;
logStartupProfileInfo ( context) ;
}
ConfigurableListableBeanFactory beanFactory = context. getBeanFactory ( ) ;
beanFactory. registerSingleton ( "springApplicationArguments" , applicationArguments) ;
if ( printedBanner != null) {
beanFactory. registerSingleton ( "springBootBanner" , printedBanner) ;
}
if ( beanFactory instanceof DefaultListableBeanFactory ) {
( ( DefaultListableBeanFactory) beanFactory) . setAllowBeanDefinitionOverriding ( this . allowBeanDefinitionOverriding) ;
}
Set< Object> sources = getAllSources ( ) ;
Assert. notEmpty ( sources, "Sources must not be empty" ) ;
load ( context, sources. toArray ( new Object [ 0 ] ) ) ;
listeners. contextLoaded ( context) ;
}
查看refreshContext方法:刷新容器
private void refreshContext ( ConfigurableApplicationContext context) {
refresh ( context) ;
if ( this . registerShutdownHook) {
try {
context. registerShutdownHook ( ) ;
} catch ( AccessControlException ex) {
}
}
}
查看afterRefresh方法:Spring容器后置处理
protected void afterRefresh ( ConfigurableApplicationContext context, ApplicationArguments args) {
}
查看第七步的start方法:监听器发出结束执行的事件通知
public void started ( ConfigurableApplicationContext context) {
for ( SpringApplicationRunListener listener : this . listeners) {
listener. started ( context) ;
}
}
查看第八步的callRunners方法:执行Runners
private void callRunners ( ApplicationContext context, ApplicationArguments args) {
List< Object> runners = new ArrayList < > ( ) ;
runners. addAll ( context. getBeansOfType ( ApplicationRunner. class ) . values ( ) ) ;
runners. addAll ( context. getBeansOfType ( CommandLineRunner. class ) . values ( ) ) ;
AnnotationAwareOrderComparator. sort ( runners) ;
for ( Object runner : new LinkedHashSet < > ( runners) ) {
if ( runner instanceof ApplicationRunner ) {
callRunner ( ( ApplicationRunner) runner, args) ;
}
if ( runner instanceof CommandLineRunner ) {
callRunner ( ( CommandLineRunner) runner, args) ;
}
}
}