源码解读全文
SpringBoot
- 整合了
Spring
和SpringMVC
- 依赖环节,抽取了各种
starter
,自动导入了很多组件 - 底层容器为
ServletWebServerApplicationContext
Run方法
- 创建IOC容器
context = createApplicationContext();
,加载配置 - 刷新IOC容器
refreshContext(context);
,进行容器刷新12大步 - 其中实际的容器类
ServletWebServerApplicationContext
,重写了onRefresh
,创建了Tomcat
服务器 Tomcat
启动,通过ServlertContextInitializer
的onStartup
回调,注册所有Servlet
DispatcherServlet
初始化机制,创建父子容器,加载九大组件
@SpringBootApplication
- 给容器中加载组件
@SpringBootConfiguration
为配置类,会被后置处理器分析@EnableAutoConfiguration
,导入组件
@AutoConfigurationPackage
,自动配置包,导入组件@Import(AutoConfigurationPackages.Registrar.class)
@Import(AutoConfigurationImportSelector.class)
AutoConfigurationPackages.Registrar
- 最终调用
registry.registerBeanDefinition(BEAN, new BasePackagesBeanDefinition(packageNames));
String BEAN = AutoConfigurationPackages.class.getName();
packageNames = com.java.boot
- 导入扫描包的定义信息,指定要扫描哪些包
- 当处理到这个
BeanDefinition
时,会进行包扫描
AutoConfigurationImportSelector
ConfigurationClassPostProcessor
处理过程中,被扫描到进行注解解析并最终调用getAutoConfigurationEntry
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//获取所有的`EnableAutoConfiguration`的属性类
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
//去重
configurations = removeDuplicates(configurations);
//排除
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
//过滤掉不能使用的类,依赖类
configurations = getConfigurationClassFilter().filter(configurations);
//发送事件
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
- 其中最终调用
loadSpringFactories
,进行懒加载并进行缓存 - 利用SPI机制,加载
"META-INF/spring.factories";
中的EnableAutoConfiguration
对应的所有配置的类
SpringBoot中的DispatcherServlet
SpringBoot
准备了一个DispatcherServlet
放入嵌入式Tomcat
中DispatcherServletAutoConfiguration
进行DispatcherServlet
的配置,需要先配置ServletWebServerFactoryAutoConfiguration
,处理ServletWeb
服务器的配置
ServletWebServerFactoryAutoConfiguration
ServerProperties.class
加载server
开头的配置- 导入
BeanPostProcessorsRegistrar.class
注册
WebServerFactoryCustomizerBeanPostProcessor
后置增强
- 导入三种不同的服务器,根据条件
@ConditionalOnClass
,决定使用哪个服务器
EmbeddedTomcat
EmbeddedJetty
EmbeddedUndertow
EmbeddedTomcat
- 注入了
TomcatServletWebServerFactory
,作为ServletWebServerFactory
服务器工厂,产生并启动服务器 - 构造参数从容器中获取
TomcatServletWebServerFactory
中包含getWebServer
创建Tomcat
过程
run
方法applicationContext.refresh();
容器为
AnnotationConfigServletWebServerApplicationContext
,为ServletWebServerApplicationContext
的子类
- 调用
super
的refresh()
,为AbstractApplicationContext
容器刷新十二大步,进行onfresh()
,由子类重写,调用createWebServer();
,创建Web服务器
- 通过
getBean
获取ServletWebServerFactory
,ServletWebServerFactory factory = getWebServerFactory();
,最终加载TomcatServletWebServerFactory
,加载Tomcat
服务器工厂
- 其中
configureContext(context, initializersToUse);
,initializersToUse
为ServlertContextInitializer
- 说明
Tomcat
启动时,需要ServlertContextInitializer
- 创建服务器,进行服务器配置
this.webServer = factory.getWebServer(getSelfInitializer());
,调用getTomcatWebServer(tomcat);
,最终this.tomcat.start();
启动
DispatcherServletAutoConfiguration
DispatcherServletRegistrationBean
通过ServlertContextInitializer
的onStartup
,在Tomcat
启动完成后,将自己注册
DispatcherServletRegistrationBean
DispatcherServletRegistrationBean
,实现了ServlertContextInitializer
- 在创建
Bean
时,需要DispatcherServlet
- 即当
TomcatServer
启动时,getWebServerFactory();
,prepareContext(tomcat.getHost(), initializers);
准备上下文
其中
ServletContextInitializer[] initializersToUse = mergeInitializers(initializers);
,获取所有initializer
,其中包括DispatcherServletRegistrationBean
- 处理上下文
configureContext(context, initializersToUse);
,创建TomcatStarter starter = new TomcatStarter(initializers);
TomcatStarter
中start
后,调用onStartup
时,其中遍历所有的initializer
,initializer.onStartup(servletContext);
- 调用
RegistrationBean
的onStartup
,register(description, servletContext);
,注册进Tomcat
中,其中也包括DispatcherServlet
DispatcherServletRegistrationBean
继承了RegistrationBean
- 最终调用
ServletRegistrationBean
的configure
,将映射信息注册registration.addMapping(urlMapping);