1.Spring Boot 简介
简化Spring应用开发的一个框架;
内嵌Servler容器
减少了配置文件
2.微服务
每一个功能元素最终都是一个可独立替换和独立升级的软件单元;
3.打包插件
<!-- 这个插件,可以将应用打包成一个可执行的jar包;-->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
将这个应用打成jar包,直接使用java -jar的命令进行执行;
4.Spring boot父POM文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
他的父项目是
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
他来真正管理Spring Boot应用里面的所有依赖版本;
Spring Boot的版本仲裁中心;
以后我们导入依赖默认是不需要写版本;(没有在dependencies里面管理的依赖自然需要声明版本号)
5.激活指定profile
1、在配置文件中指定 spring.profiles.active=dev
2、命令行:
java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev;
可以直接在测试的时候,配置传入命令行参数
3、虚拟机参数;
-Dspring.profiles.active=dev
6.配置文件加载位置
springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件
–file:./config/
–file:./
–classpath:/config/
–classpath:/
优先级由高到底,高优先级的配置会覆盖低优先级的配置;
SpringBoot会从这四个位置全部加载主配置文件;互补配置;
7.spring boot启动器
导入web容器正常运行所依赖组件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器
8.spring启动原理
/**
* @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
*/
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args) {
// Spring应用启动起来
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}
@SpringBootApplication: Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot运行这个类的main方法来启动SpringBoot应用;
6.1 springBootApplication注解信息
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
//是个配置类
@Configuration(proxyBeanMethods = false)
public @interface SpringBootConfiguration {}
6.2 @SpringBootConfiguration
- @SpringBootConfiguration:Spring Boot的配置类,标注在某个类上,表示这是一个Spring Boot的配置类;
- @Configuration:配置类上来标注这个注解;是个配置类,代替以前的配置文件,配置类也是容器中的一个组件;@Component
6.3@EnableAutoConfiguration
@EnableAutoConfiguration:开启自动配置功能,以前我们需要配置的东西,Spring Boot帮我们自动配置;告诉SpringBoot开启自动配置功能;这样自动配置才能生效;
@AutoConfigurationPackage//自动配置包
@Import(EnableAutoConfigurationImportSelector.class)//给容器中导入一个组件,导入的组件由AutoConfigurationPackages.Registrar.class;
public @interface EnableAutoConfiguration {}
- @AutoConfigurationPackage:自动配置包
@Import(AutoConfigurationPackages.Registrar.class):给容器中导入一个组件,主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)//给容器中导入一个组件,导入的组件由AutoConfigurationPackages.Registrar.class;
public @interface AutoConfigurationPackage {}
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
//主配置类的所在包及下面所有子包里面的所有组件扫描到Spring容器
register(registry, new PackageImport(metadata).getPackageName());
}
}
-
@Import(EnableAutoConfigurationImportSelector.class)
给容器导入EnableAutoConfigurationImportSelector组件,将所有需要导入的组件以全类名的方式返回,这些组件将被添加都容器中 ,**会给容器中导入非常多的自动配置类(xxxAutoConfiguration);就是给容器中导入这个场景需要的所有组件,并配置好这些组件;**有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;@Override public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); } //核心在getAutoConfigurationEntry里面的 List<String> configurations =SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); //扫描所有jar包从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration**指定的值(上面截图),将这些值作为自动配置类导入到容器中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UYCPJtHY-1576169155091)(/Users/laiyanxin/Library/Application Support/typora-user-images/image-20191209230257265.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p3ncr8O5-1576169155093)(/Users/laiyanxin/Library/Application Support/typora-user-images/image-20191209230646961.png)]
里面SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);主要是Spring Boot在启动的时候扫描所有jar包从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值(上面截图),将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作;以前我们需要自己配置的东西,自动配置类都帮我们
- 以**HttpEncodingAutoConfiguration(Http编码自动配置)**为例解释自动配置原理;
@Configuration(proxyBeanMethods = false)//表示这个一个配置类,以前编写的配置文件一样,也可以给容器添加组件
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {}
9.SpringMVC自动配置原理
9.1Spring MVC auto-configuration
官方文档解释
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
The auto-configuration adds the following features on top of Spring’s defaults:
- Inclusion of
ContentNegotiatingViewResolver
andBeanNameViewResolver
beans.- 自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染(是转发还是重定向)
- ContentNegotiatingViewResolver组合了所有视图解析器
- 我们可以自己给容器中添加一个视图解析器;自动的将其组合进来.会加入ContentNegotiatingViewResolver
- Support for serving static resources, including support for WebJars (see below).
支持静态资源文件webjar - Automatic registration of
Converter
,GenericConverter
,Formatter
beans.- 自动注册了
Converter
,GenericConverter
,Formatter
beans Converter
:转换器,例子:我们接受对象Person,类型转换用ConverterFormatter
:格式化器;例子:前端传2019.12.12通过格式化器转成Date- 自己添加的格式化器转换器,我们只需要放在容器中即可=
- 自动注册了
- Support for
HttpMessageConverters
(see below).- HttpMessageConverter:SpringMVC用来转换Http请求和响应的;User—Json;
HttpMessageConverters
是从容器中确定;获取所有的HttpMessageConverter;- 自己给容器中添加HttpMessageConverter,只需要将自己的组件注册容器中@Bean,@Component
- Automatic registration of
MessageCodesResolver
(see below).
定义错误代码生成规则 - Static
index.html
support. 静态首页访问 - Custom
Favicon
support (see below). - Automatic use of a
ConfigurableWebBindingInitializer
bean (see below).- 我们可以配置一个ConfigurableWebBindingInitializer来替换默认的
- 初始化WebDataBinder;请求数据=====JavaBean;
If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own @Configuration
class of type WebMvcConfigurerAdapter
, but without @EnableWebMvc
. If you wish to provide custom instances of RequestMappingHandlerMapping
, RequestMappingHandlerAdapter
or ExceptionHandlerExceptionResolver
you can declare a WebMvcRegistrationsAdapter
instance providing such components.
If you want to take complete control of Spring MVC, you can add your own @Configuration
annotated with @EnableWebMvc
.
9.2、扩展SpringMVC
编写一个配置类(@Configuration),是WebMvcConfigurerAdapter类型;不能标注@EnableWebMvc
既保留了所有的自动配置,也能用我们扩展的配置;
使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
//浏览器发送 /xx 请求来到 success
registry.addViewController("/xx").setViewName("success");
}
}
原理:
-
WebMvcAutoConfiguration是SpringMVC的自动配置类
-
在做其他自动配置时会导入;@Import(EnableWebMvcConfiguration.class)
@Configuration public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration { private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite(); //从容器中获取所有的WebMvcConfigurer List<WebMvcConfigurer> configurers @Autowired(required = false) public void setConfigurers(List<WebMvcConfigurer> configurers) { if (!CollectionUtils.isEmpty(configurers)) { this.configurers.addWebMvcConfigurers(configurers); //一个参考实现;将所有的WebMvcConfigurer相关配置都来一起调用; @Override // public void addViewControllers(ViewControllerRegistry registry) { // for (WebMvcConfigurer delegate : this.delegates) { // delegate.addViewControllers(registry); // } } } }
-
容器中所有的WebMvcConfigurer都会一起起作用;
-
我们的配置类也会被调用;
效果:SpringMVC的自动配置和我们的扩展配置都会起作用;
9.3全面接管SpringMVC
SpringBoot对SpringMVC的自动配置不需要了,所有都是我们自己配置;所有的SpringMVC的自动配置都失效了我们需要在配置类中添加@EnableWebMvc即可
//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
@EnableWebMvc
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// super.addViewControllers(registry);
//浏览器发送 /atguigu 请求来到 success
registry.addViewController("/atguigu").setViewName("success");
}
}
原理:为什么@EnableWebMvc自动配置就失效了;
-
@EnableWebMvc的核心
@Import(DelegatingWebMvcConfiguration.class) public @interface EnableWebMvc {
-
@Configuration public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {}
-
容器中没有WebMvcConfigurationSupport这个组件的时候,这个自动配置类才生效
@Configuration @ConditionalOnWebApplication @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurerAdapter.class }) //容器中没有这个组件的时候,这个自动配置类才生效 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10) @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class }) public class WebMvcAutoConfiguration {
-
@EnableWebMvc将WebMvcConfigurationSupport组件导入进来;
-
导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能;
10.如何修改SpringBoot的默认配置
- SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;
- 在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置
- 在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置
11.嵌入式Servlet容器自动配置原理
EmbeddedServletContainerAutoConfiguration:嵌入式的Servlet容器自动配置
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration
@ConditionalOnWebApplication
@Import(BeanPostProcessorsRegistrar.class)
//导入BeanPostProcessorsRegistrar:给容器中导入一些组件
//导入了EmbeddedServletContainerCustomizerBeanPostProcessor:
public class EmbeddedServletContainerAutoConfiguration {
@Configuration
@ConditionalOnClass({ Servlet.class, Tomcat.class })//判断当前是否引入了Tomcat依赖;
@ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)//判断当前容器没有用户自己定义EmbeddedServletContainerFactory:嵌入式的Servlet容器工厂;作用:创建嵌入式的Servlet容器
public static class EmbeddedTomcat {
@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
return new TomcatEmbeddedServletContainerFactory();
}
}
/**
*判断当前是否引入了Jetty依赖;
**/
@Configuration
@ConditionalOnClass({ Servlet.class, Server.class, Loader.class,
WebAppContext.class })
@ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedJetty {
@Bean
public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
return new JettyEmbeddedServletContainerFactory();
}
}
/**
* 判断当前是否引入了Undertow依赖
*/
@Configuration
@ConditionalOnClass({ Servlet.class, Undertow.class, SslClientAuthMode.class })
@ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedUndertow {
@Bean
public UndertowEmbeddedServletContainerFactory undertowEmbeddedServletContainerFactory() {
return new UndertowEmbeddedServletContainerFactory();
}
}
springboot会根据你导入的依赖来选择servlet容器
3)、以TomcatEmbeddedServletContainerFactory为例
@Override
public EmbeddedServletContainer getEmbeddedServletContainer(
ServletContextInitializer... initializers) {
//创建一个Tomcat
Tomcat tomcat = new Tomcat();
//配置Tomcat的基本环节
File baseDir = (this.baseDirectory != null ? this.baseDirectory
: createTempDir("tomcat"));
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
tomcat.getService().addConnector(connector);
customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
//将配置好的Tomcat传入进去,返回一个EmbeddedServletContainer;并且启动Tomcat服务器
return getTomcatEmbeddedServletContainer(tomcat);
}
4)、我们对嵌入式容器的配置修改是怎么生效?
可以通过ServerProperties(也是定制器)配置文件、EmbeddedServletContainerCustomizer 定制器帮我们修改
5)、修改的原理
容器中导入了EmbeddedServletContainerCustomizerBeanPostProcessor
//初始化之前
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
//如果当前初始化的是一个ConfigurableEmbeddedServletContainer类型的组件
if (bean instanceof ConfigurableEmbeddedServletContainer) {
//
postProcessBeforeInitialization((ConfigurableEmbeddedServletContainer) bean);
}
return bean;
}
private void postProcessBeforeInitialization(
ConfigurableEmbeddedServletContainer bean) {
//获取所有的定制器,调用每一个定制器的customize方法来给Servlet容器进行属性赋值;
for (EmbeddedServletContainerCustomizer customizer : getCustomizers()) {
customizer.customize(bean);
}
}
private Collection<EmbeddedServletContainerCustomizer> getCustomizers() {
if (this.customizers == null) {
// Look up does not include the parent context
this.customizers = new ArrayList<EmbeddedServletContainerCustomizer>(
this.beanFactory
//从容器中获取所有这葛类型的组件:EmbeddedServletContainerCustomizer
//定制Servlet容器,给容器中可以添加一个EmbeddedServletContainerCustomizer类型的组件
.getBeansOfType(EmbeddedServletContainerCustomizer.class,
false, false)
.values());
Collections.sort(this.customizers, AnnotationAwareOrderComparator.INSTANCE);
this.customizers = Collections.unmodifiableList(this.customizers);
}
return this.customizers;
}
步骤:
1)、SpringBoot根据导入的依赖情况,给容器中添加相应的EmbeddedServletContainerFactory【TomcatEmbeddedServletContainerFactory】
2)、容器中某个组件要创建对象就会通过后置处理器;EmbeddedServletContainerCustomizerBeanPostProcessor;
只要是嵌入式的Servlet容器工厂,后置处理器就工作;
3)、后置处理器,从容器中获取所有的EmbeddedServletContainerCustomizer,调用定制器的定制方法
12嵌入式的Servlet容器启动原理
什么时候创建嵌入式的Servlet容器工厂?什么时候获取嵌入式的Servlet容器并启动Tomcat;
IOC容器启动创建嵌入式的Servlet容器
源码:
获取嵌入式的Servlet容器工厂:
1)、SpringBoot应用启动运行run方法
2)、refreshContext(context);
SpringBoot刷新IOC容器【创建IOC容器对象,并初始化容器,创建容器中的每一个组件】;如果是web应用创建AnnotationConfigEmbeddedWebApplicationContext,否则:AnnotationConfigApplicationContext
3)、refresh(context);刷新刚才创建好的ioc容器;
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
4)、 onRefresh(); web的ioc容器重写了onRefresh方法
5)、webioc容器会创建嵌入式的Servlet容器;createEmbeddedServletContainer();
6)、获取嵌入式的Servlet容器工厂:
EmbeddedServletContainerFactory containerFactory = getEmbeddedServletContainerFactory();
从ioc容器中获取EmbeddedServletContainerFactory 组件;TomcatEmbeddedServletContainerFactory创建对象,后置处理器一看是这个对象,就获取所有的定制器来先定制Servlet容器的相关配置;
7)、使用容器工厂获取嵌入式的Servlet容器:this.embeddedServletContainer = containerFactory .getEmbeddedServletContainer(getSelfInitializer());
8)、嵌入式的Servlet容器创建对象并启动Servlet容器;
先启动嵌入式的Servlet容器,再将ioc容器中剩下没有创建出的对象获取出来;
13启动原理
启动流程
1.创建SpringApplication对象,在该对象初始化时,找到配置的事件监听器,并保存起来
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
return new SpringApplication(sources).run(args);
}
public SpringApplication(Object... sources) {
initialize(sources);
}
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配置的所有ApplicationContextInitializer;然后保存起来
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
//从类路径下找到ETA-INF/spring.factories配置的所有ApplicationListener
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
//从多个配置类中找到有main方法的主配置类
this.mainApplicationClass = deduceMainApplicationClass();
}
2.运行run方法
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
FailureAnalyzers analyzers = null;
configureHeadlessProperty();
//1.获取SpringApplicationRunListeners;从类路径下META-INF/spring.factories
SpringApplicationRunListeners listeners = getRunListeners(args);
//2/回调所有的SpringApplicationRunListeners的starting
listeners.starting();
try {
//3.封装命令航参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(
args);
//4.准备环境,回调SpringApplicationRunListeners的environmentPrepared,表示环境准保完成
ConfigurableEnvironment environment = prepareEnvironment(listeners,
applicationArguments);
//5.打印banner
Banner printedBanner = printBanner(environment);
//6.根据环境来决定是创建Web还是IOC容器
context = createApplicationContext();
analyzers = new FailureAnalyzers(context);
//7.准备上下文环境,
//7.1回调上一步保存的所有ApplicationContextInitializer的initialize方法
//7.2回调SpringApplicationRunListeners的contextPrepared
//7.3最后一步回调SpringApplicationRunListeners的contextLoaded
prepareContext(context, environment, listeners, applicationArguments,
printedBanner);
//8.刷新容器(如果是web应用还会创建嵌入式的Tomca).扫描,创建,加载所有组件的地方;(配置类,组件,自动配置)
refreshContext(context);
//9.从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调
//ApplicationRunner先回调,CommandLineRunner再回调
afterRefresh(context, applicationArguments);
//10回调SpringApplicationRunListeners的finished
listeners.finished(context, null);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass)
.logStarted(getApplicationLog(), stopWatch);
}
//整个SpringBoot应用启动完成以后返回启动的ioc容器;
return context;
}
catch (Throwable ex) {
handleRunFailure(context, listeners, analyzers, ex);
throw new IllegalStateException(ex);
}
}
- 获取SpringApplicationRunListeners;从类路径下META-INF/spring.factories
- 回调所有的SpringApplicationRunListeners的starting
- 封装命令行参数
- 准备环境,回调SpringApplicationRunListeners的environmentPrepared,表示环境准保完成
- 打印banner
- 根据环境来决定是创建Web还是IOC容器
- 准备上下文环境,
- 7.1回调上一步保存的所有ApplicationContextInitializer的initialize方法
- 7.2回调SpringApplicationRunListeners的contextPrepared
- 7.3最后一步回调SpringApplicationRunListeners的contextLoaded
- 刷新容器(如果是web应用还会创建嵌入式的Tomca).扫描,创建,加载所有组件的地方;(配置类,组件,自动配置)
- 从ioc容器中获取所有的ApplicationRunner和CommandLineRunner进行回调,ApplicationRunner先回调,CommandLineRunner再回调
- 回调SpringApplicationRunListeners的finished
- 整个SpringBoot应用启动完成以后返回启动的ioc容器;