springboot源码流程解析
2021-10-30 09:59:17 32 举报
AI智能生成
springboot源码流程解析
作者其他创作
大纲/内容
1.启动流程
SpringApplication.run(HibikiApplication.class, args);
--run(new Class<?>[] { primarySource }, args)
----new SpringApplication(primarySources).run(args)
--run(new Class<?>[] { primarySource }, args)
----new SpringApplication(primarySources).run(args)
this(resourceLoader:null, primarySources);
this.resourceLoader = resourceLoader;
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
REACTIVE
NONE
SERVLET
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
getSpringFactoriesInstances(ApplicationContextInitializer.class,new Class<?>[] {})
getClassLoader()
Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader))
>>loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList())
>>loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList())
(List)loadSpringFactories(classLoader)
getOrDefault(factoryTypeName, Collections.emptyList()
List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names)
setInitializers
--this.initializers = new ArrayList<>(initializers)
--this.initializers = new ArrayList<>(initializers)
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
--this.listeners = new ArrayList<>(listeners);
--this.listeners = new ArrayList<>(listeners);
this.mainApplicationClass = deduceMainApplicationClass();
#run(args)
ConfigurableApplicationContext context = null
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>()
SpringApplicationRunListeners listeners = getRunListeners(args);
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args))
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args))
listeners.starting()
this.initialMulticaster.multicastEvent(new ApplicationStartingEvent(this.application, this.args));
RestartApplicationListener#onApplicationStartingEvent
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args)
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
若没有显示指定容器的类型,则根据this.webApplicationType创建class
若为SERVLET,创建AnnotationConfigServletWebServerApplicationContext,反射实例化
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
new Class[] { ConfigurableApplicationContext.class }, context);
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
context.setEnvironment(environment)
postProcessApplicationContext(context);
applyInitializers(context);
循环依次initializer.initialize(context)
listeners.contextPrepared(context);
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
若this.lazyInitialization:默认false,可在yaml配置main:lazy-initialization:true
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor())
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor())
Set<Object> sources = getAllSources();
load(context, sources.toArray(new Object[0]))
listeners.contextLoaded(context);
refreshContext(context);
refresh((ApplicationContext) context);
大部分与普通springioc容器流程相同,详情见springioc流程分析
不同点
#invokeBeanFactoryPostProcessors
ServletWebServerApplicationContext#Onfresh
this.themeSource = UiApplicationContextUtils.initThemeSource(this);
createWebServer()
ServletWebServerFactory factory = getWebServerFactory();
String[] beanNames = getBeanFactory().getBeanNamesForType(ServletWebServerFactory.class)
>>return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class)
>>return getBeanFactory().getBean(beanNames[0], ServletWebServerFactory.class)
this.webServer = factory.getWebServer(getSelfInitializer());
getSelfInitializer()
--return this::selfInitialize: 传入方法引用,匿名函数,在之后webServer初始化时调用
>>>>selfInitialize(ServletContext servletContext)
--return this::selfInitialize: 传入方法引用,匿名函数,在之后webServer初始化时调用
>>>>selfInitialize(ServletContext servletContext)
prepareWebApplicationContext(servletContext);
Object rootContext = servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this);
setServletContext(servletContext);
registerApplicationScope(servletContext);
ServletContextScope appScope = new ServletContextScope(servletContext);
getBeanFactory().registerScope(“application”, appScope);
servletContext.setAttribute(ServletContextScope.class.getName(), appScope);
WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext);
--registerEnvironmentBeans(bf, sc, (ServletConfig)null);
----bf.registerSingleton("servletContext", servletContext);
----bf.registerSingleton("contextParameters", Collections.unmodifiableMap(attributeMap));
----bf.registerSingleton("contextAttributes", Collections.unmodifiableMap(attributeMap));
--registerEnvironmentBeans(bf, sc, (ServletConfig)null);
----bf.registerSingleton("servletContext", servletContext);
----bf.registerSingleton("contextParameters", Collections.unmodifiableMap(attributeMap));
----bf.registerSingleton("contextAttributes", Collections.unmodifiableMap(attributeMap));
for (ServletContextInitializer beans : getServletContextInitializerBeans())
>>beans.onStartup(servletContext);
>>beans.onStartup(servletContext);
getServletContextInitializerBeans()
--return new ServletContextInitializerBeans(getBeanFactory());
----addServletContextInitializerBeans(beanFactory);
----addAdaptableBeans(beanFactory);
--return new ServletContextInitializerBeans(getBeanFactory());
----addServletContextInitializerBeans(beanFactory);
----addAdaptableBeans(beanFactory);
getWebServer(ServletContextInitializer... initializers)
Tomcat tomcat = new Tomcat();
prepareContext(tomcat.getHost(), initializers);
TomcatEmbeddedContext context = new TomcatEmbeddedContext();
addDefaultServlet(context);
configureContext(context, initializersToUse);
TomcatStarter starter = new TomcatStarter(initializers);
for (TomcatContextCustomizer customizer : this.tomcatContextCustomizers) {
customizer.customize(context);
}
customizer.customize(context);
}
postProcessContext(context);
return getTomcatWebServer(tomcat);
--return new TomcatWebServer(tomcat, getPort() >= 0, getShutdown());
--return new TomcatWebServer(tomcat, getPort() >= 0, getShutdown());
getBeanFactory().registerSingleton("webServerGracefulShutdown",
new WebServerGracefulShutdownLifecycle(this.webServer));
new WebServerGracefulShutdownLifecycle(this.webServer));
getBeanFactory().registerSingleton("webServerStartStop",
new WebServerStartStopLifecycle(this, this.webServer));
new WebServerStartStopLifecycle(this, this.webServer));
GenericWebApplicationContext#initPropertySources();
--ConfigurableEnvironment env = this.getEnvironment();
--env.initPropertySources(this.servletContext, (ServletConfig)null);
----WebApplicationContextUtils.initServletPropertySources(this.getPropertySources(), servletContext, servletConfig);
--ConfigurableEnvironment env = this.getEnvironment();
--env.initPropertySources(this.servletContext, (ServletConfig)null);
----WebApplicationContextUtils.initServletPropertySources(this.getPropertySources(), servletContext, servletConfig);
sources.replace("servletContextInitParams", new ServletContextPropertySource("servletContextInitParams", servletContext));
sources.replace("servletConfigInitParams", new ServletConfigPropertySource("servletConfigInitParams", servletConfig));
#registerListeners
详情见springioc流程分析
#finishRefresh
getLifecycleProcessor().onRefresh();
DefaultLifecycleProcessor#startBeans(true);
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
webServerStartStop#start
this.webServer.start();
this.running = true;
this.applicationContext.publishEvent
(new ServletWebServerInitializedEvent(this.webServer, this.applicationContext));
(new ServletWebServerInitializedEvent(this.webServer, this.applicationContext));
webServerGracefulShutdown
根据各个bean不同的应用阶段分组
调用LifecycleGroup中的所有Lifecycle的start方法
this.running = true;
this.webServer.start()
context.registerShutdownHook();
afterRefresh(context, applicationArguments);
listeners.started(context);
callRunners(context, applicationArguments);
List<Object> runners = new ArrayList<>();
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
循环callRunner((CommandLineRunner) runner, args);
listeners.running(context);
2.@SpringBootApplication
@SpringBootConfiguration
@Configuration
@Component
说明Spring的配置类也是Spring的一个组件
@ComponentScan(excludeFilters = {x,x})
AutoConfigurationExcludeFilter
TypeExcludeFilter
@EnableAutoConfiguration
@AutoConfigurationPackage
@Import(AutoConfigurationPackages.Registrar.class)
自动注册包---主配置类所在的包:com.kuang.demo包
自动注册包---主配置类所在的包:com.kuang.demo包
#registerBeanDefinitions
@Import(AutoConfigurationImportSelector.class)自动导入包的核心
#selectImports(AnnotationMetadata annotationMetadata)
#isEnabled(AnnotationMetadata metadata)
#getAutoConfigurationEntry(AnnotationMetadata annotationMetadata)
#getCandidateConfigurations(annotationMetadata, attributes)
导入的类:自动导入选择器AutoConfigurationImportSelector
类里有个方法:getAutoConfigurationEntry
作用:获得自动配置实体
作用:获得自动配置实体
该方法里调用了方法:getCandidateConfigurations
目的:获取候选的配置
目的:获取候选的配置
该方法调用了
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader())
关注参数 最后返回的就是自动配置的类:就是META-INF/factories下的自动配置类名的集合
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader())
关注参数 最后返回的就是自动配置的类:就是META-INF/factories下的自动配置类名的集合
getSpringFactoriesLoaderFactoryClass()
return EnableAutoConfiguration.class;
获取标注了EnableAutoConfiguration这个注解的类:
包括主启动类public class Application
return EnableAutoConfiguration.class;
获取标注了EnableAutoConfiguration这个注解的类:
包括主启动类public class Application
应用
自定义运行监听器
implements SpringApplicationRunListener
extends EventPublishingRunListener
extends EventPublishingRunListener
写入factories中
插手ServletContext初始化工作
implements ServletContextInitializer
自定义配置嵌入式Servlet容器
implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>
mvc自定义配置
implements WebMvcConfigurer
自定义事件
extends ApplicationEvent
ApplicationContext.publishEvent(“”)
自定义事件监听器
容器事件
implements ApplicationListener<ApplicationEvent>
implements GenericApplicationListener
要想从容器创建开始就监听所有事件,在spring.factories配置
key=org.springframework.context.ApplicationListener
key=org.springframework.context.ApplicationListener
请求事件
extends RequestContextListener
插手容器启动时提供参数
implements ApplicationRunner
implements CommandLineRunner
3.ApplicationContextInitializer(系统初始化器
1.ApplicationContextInitializer 介绍
新建一个类 MyApplicationContextInitializer 并实现 ApplicationContextInitializer 接口
SpringBoot的main方法application.addInitializers
application.properties配置
SpringBoot的SPI扩展---META-INF/spring.factories中配置
4.监听器Listenter
SpringBoot框架事件
图片
获取监听器列表
图片
触发机制
图片
自定监听器
5.Bean的创建
图片
6.Banner解析
7.计时器
StopWatch用来统计任务的耗时
8.启动类加载器
9.Spring Boot starter介绍以及自定义starter
1.starter介绍
2.自定义starter
pom文件添加spring-boot-autoconfigure和spring-boot-configuration-processor
创建PriceAutoConfiguration。增加注解EnableConfigurationProperties, ConditionalOnProperty
spring.factories中添加自动配置类实现
3.源码解析
图片
原理
4.webflux解析
WebFlux请求处理流程
图片
0 条评论
下一页