springboot启动流程详解
2023-02-28 18:08:06 0 举报
AI智能生成
登录查看完整内容
基于spring-webmvc的springboot2.5版本启动流程。涉及spring spi,BeanDifition,FactoryBean/常规Bean的后置处理,Spring三级缓存部分解决循环依赖,spring常用扩展点
作者其他创作
大纲/内容
属性:this.resourceLoader。ResourceLoader
属性:this.primarySources。Set<Class<?>>
WebApplicationType.NONE
WebApplicationType.SERVLET (spring-webmvc.jar)
WebApplicationType.REACTIVE(spring-webflux.jar)
WebApplicationType.deduceFromClasspath()
属性:this.webApplicationType。WebApplicationType
getBootstrapRegistryInitializersFromSpringFactories
getSpringFactoriesInstances
loadSpringFactories
SpringFactoriesLoader.loadFactoryNames
读取项目所有jar下的META-INF/spring.factories,加载各种功能工厂及对应的实现类
createSpringFactoriesInstances
AnnotationAwareOrderComparator.sort
属性:this.bootstrapRegistryInitializers。ArrayList<BootstrapRegistryInitializer>
getSpringFactoriesInstances(ApplicationContextInitializer.class)
方法:setInitializers
通过项目所有jar包下的META-INF/spring.factories,获取并应用上下文初始化器实例,并且设置属性集合 List<ApplicationContextInitializer<?>>
getSpringFactoriesInstances(ApplicationListener.class)
方法:setListeners
通过项目所有jar包下的META-INF/spring.factories,获取并应用监听实例,并且设置属性集合List<ApplicationListener<?>>
deduceMainApplicationClass()
属性:this.mainApplicationClass。Class<?>
设置主应用类,通过判断含有main方法的track获取。 即程序启动入口所在的类
SpringApplication实例化(以下简称SA实例)
设置ResourceLoader,默认为null
设置多个主要的bean来源,默认的是一个,通常设置main方法所在的类
通过判断引入jar特有的classPath判断应用类型
主要通过加载所有jar包下的META-INF/spring.factories,获取各种引导注册工厂实现类的实例
extends interface BootstrapRegistry
extends interface BootstrapContext
implements interface ConfigurableBootstrapContext
创建内部变量 DefaultBootstrapContext
遍历SA实例的引导注册器实例列表(bootstrapRegistryInitializers)。对列表例的实例,使用DefaultBootstrapContext入参进行初始化。initialize(BootstrapRegistry )
createBootstrapContext()
参考例子org.springframework.cloud.netflix.eureka.config.EurekaConfigServerBootstrapper
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
该jar下META-INF/spring.factories有配置Bootstrapper注册
configureHeadlessProperty()
getRunListeners(args)
例子:org.springframework.boot.context.event.EventPublishingRunListener
SpringApplicationRunListeners listeners
在所有jar下META-INF/spring.factories获取 接口SpringApplicationRunListener.class实现类的实例
对所有listeners实例,执行监听启动方法,入参DefaultBootstrapContext
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args)
extends PropertyResolver
extends ConfigurablePropertyResolver
ConfigurableEnvironment关系
getOrCreateEnvironment()推断应用环境,这里是ApplicationServletEnvironment对象
如果有ConversionService设置环境setConversionService
配置PropertySources。解析arg参数或命令行参数封装到MutablePropertySources
配置Profiles。例如spring.profiles.active参数
bindToSpringApplication
绑定环境到SA实例
发送环境准备消息,此时应用上下文没有创建
Banner printedBanner = printBanner(environment);
extends EnvironmentCapable
extends BeanFactory
extends ListableBeanFactory
extends HierarchicalBeanFactory
extends MessageSource
extends ApplicationEventPublisher
extends ResourceLoader
extends ResourcePatternResolver
extends ApplicationContext
extends Lifecycle
extends AutoCloseable
extends Closeable
ConfigurableApplicationContext ; interface
ApplicationContextFactory applicationContextFactory = ApplicationContextFactory.DEFAULT;
return this.applicationContextFactory.create(this.webApplicationType);
createApplicationContext()
implements ResourceLoader
extends DefaultResourceLoader
详见上文 ConfigurableApplicationContext关系
implements ConfigurableApplicationContext
extends AbstractApplicationContext
extends AliasRegistry
implements BeanDefinitionRegistry
extends GenericApplicationContext
extends WebApplicationContext
详见上文 ConfigurableApplicationContext关系
extends ConfigurableApplicationContext
implements ConfigurableWebApplicationContext
implements ThemeSource
extends GenericWebApplicationContext
详见上文 ApplicationContext关系
extends WebServerApplicationContext
implements ConfigurableWebServerApplicationContext
extends ServletWebServerApplicationContext
implements AnnotationConfigRegistry
关系
属性:AnnotatedBeanDefinitionReader reader
属性:ClassPathBeanDefinitionScanner scanner
implements AliasRegistry
extends SimpleAliasRegistry
implements SingletonBeanRegistry
extends DefaultSingletonBeanRegistry
extends FactoryBeanRegistrySupport
extends SingletonBeanRegistry
implements ConfigurableBeanFactory
extends AbstractBeanFactory
implements AutowireCapableBeanFactory
extends AbstractAutowireCapableBeanFactory
extends BeanFactory
extends AutowireCapableBeanFactory
关系见上文 implements ConfigurableBeanFactory
extends ConfigurableBeanFactory
implements ConfigurableListableBeanFactory
implements Serializable
DefaultListableBeanFactory
DefaultListableBeanFactory实例
初始化父类的父类的父类属性beanFactory 为DefaultListableBeanFactory实例
k: org.springframework.context.annotation.internalConfigurationAnnotationProcessorv: ConfigurationClassPostProcessor.class
k: org.springframework.context.annotation.internalAutowiredAnnotationProcessorv: AutowiredAnnotationBeanPostProcessor.class
k: org.springframework.context.annotation.internalCommonAnnotationProcessorv: CommonAnnotationBeanPostProcessor.class
k: org.springframework.context.event.internalEventListenerProcessorv: EventListenerMethodProcessor.class
k: org.springframework.context.event.internalEventListenerFactoryv: DefaultEventListenerFactory
创建各种注解配置类的发布处理器(AnnotationProcessor)实例,并设置为rootBeanDefition注册到beanFactory的属性beanDefinitionMap
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
根据上下文registry推断使用ConfigurableListableBeanFactory,设置ClassLoader,ResourceLoader等
this.reader = new AnnotatedBeanDefinitionReader(this)
this.scanner = new ClassPathBeanDefinitionScanner(this)
因为spring-webmvc的配置应用上下文是AnnotationConfigServletWebServerApplicationContext且其上级关系实现了接口BeanDefinitionRegistry,所以上述的this是AnnotationConfigServletWebServerApplicationContext对象
默认构造方法 AnnotationConfigServletWebServerApplicationContext()
AnnotationConfigServletWebServerApplicationContext
注解类bean定义注册器,代替classPath扫描Bean定义注册器
classPath扫描bean定义注册器,用于给定的BeanFactory或ApplicationContext创建bean
ConfigurableApplicationContext context = createApplicationContext();
函数式接口ApplicationContextFactory,相当于工厂模式设计,根据webType返回对应的应用上下文。spring-webmvc返回的是AnnotationConfigServletWebServerApplicationContext
context.setApplicationStartup(this.applicationStartup);
context.setEnvironment(environment);
postProcessApplicationContext(context)
applyInitializers(ConfigurableApplicationContext )
listeners.contextPrepared(context);
bootstrapContext.close(context);
针对符合GroovyBeanDefinitionSource.class可用
创建AnnotatedGenericBeanDefinition作用定义mateDatal类属性为StandardAnnotationMetadata把启动类所有注解类赋值到annotationTypes 等等
setBeanClass(beanClass);beanClass 是启动类
AnnotationMetadata.introspect(Class<?> type)
StandardAnnotationMetadata.from(type)
调用启动类的Clss类方法getDeclaredAnnotations,获取启动类所有注解信息
完成创建AnnotatedGenericBeanDefinition adb
this.annotatedReader.register(source)这里的source是启动类
把springboot默认入口的类对象,注册到beanFactory实例的属性beanDeafintionNames,beanDeafinitionMaps
针对注解类bean注册器使用
load(Class<?> )
load(Resource )
load(Package )
load(CharSequence)
loader.load()
针对classPath扫描bean定义使用
针对xmlbean注册器,groovybean注册器使用
listeners.contextLoaded(context)
创建Bean定义加载器,设置属性beanSource,注解类bean注册器,classPath扫描bean定义注册器,xmlbean注册器,groovybean注册器等(createApplicationContext()已生成这些对象)
通知SpringApplicationRunListeners 集合触发上下文加载事件,事件在上下文刷新之前
配置应用上下文设置环境参数
处理应用上下文
给初始化器集合(ApplicationContextInitializer)赋值应用上下文初始化
通知所有SpringApplicationRunListeners 发布上文已就绪事件
关闭应用启动上下文
加载启动类到beanDefitionMaps
调用ConfigurableApplicationContext的父类AbstractApplicationContext方法refresh()
refreshContext(ConfigurableApplicationContext )
上下文状态设置 AbstractApplicationContext
initPropertySources()
getEnvironment().validateRequiredProperties()
this.earlyApplicationListenersthis.applicationListeners
this.earlyApplicationEvents = new LinkedHashSet<>()
prepareRefresh()
初始化之前环境准备工作时占位的PropertySource的值,具体看类StandardServletEnvironment
所有属性必要性校验,具体看ConfigurablePropertyResolver#setRequiredProperties
较早应用监听事件为空,用当前的应用监听事件赋值;否则清空当前应用监听事件,并用较早的应用事件赋值
收集早期应用监听事件,等multicaster初始化完成后发布。 在后面registerListeners()阶段执行
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory()
prepareBeanFactory(beanFactory)
子类实现方法,如GenericWebApplicationContext
postProcessBeanFactory(beanFactory)
beanFactory实例化后的后置处理,GenericWebApplicationContext的实现是,设置ServletContextAwareProcessor后置处理注册web-specific的作用域,注册ServletRequest,ServletResponse,HttpSession,WebRequest创建解决工厂类。注册web-specific环境参数,如\"contextParameters\
Set<String> processedBeans = new HashSet<>() 已处理的bean
遍历入参beanFactoryPostProcessors,获取postProcessor。分别判断是否BeanDefinitionRegistryPostProcessor实例。是则执行.postProcessBeanDefinitionRegistry(registry)。并加入registryProcessors,否则加入常规regularPostProcessors
判断ConfigurationClassPostProcessor是否PriorityOrdered.class实现类 (是)
getBean是一个核心方法,里面有spring三级缓存解决循环依赖的原理
以ConfigurationClassPostProcessor为例子,解析invokeBeanDefinitionRegistryPostProcessors 方法。其核心是执行BeanDefinitionRegistryPostProcessor接口实现类的方法postProcessBeanDefinitionRegistry。 实现应用上下文初始化之后,在beanDefition注册到beanFactoy前,对beanDefition进行修改。此时bean还没有实例化
获取beanFatroy所有beanDefitionNames
判断beanDefition是否configurationClass属性,是则加入configCandidates最后判断 启动类有AnnotatedGenericBeanDefinition(上述prepareContext时候设置)
最终执行是AnnotatedBeanDefinition类的prase方法
执行prase(configCandidates) 方法
处理所有 @PropertySource 注解,创建PropertySource对象加入到Environment对象中
通过递归获取@ComponentScan上所有信息,包括注解属性值。这里的重点是获取了启动类@SpringBootApplication 的属性scanBasePackages = {\"com.xxx\"} @SpringBootApplication包含@SpringBootConfiguration包含@Configuration包含@Component
pars方法里获取basePackageClasses 即com.xxx ,然后执行ClassPathBeanDefinitionScanner.doScan(String... basePackages)
如果是AbstractBeanDefinition的实例, 判断是否需要注入其它bean,如果需要设置注入候选状态
如果是AnnotatedBeanDefinition的实例,判断是注解是否需要设置各种属性,例如lazy,dependsOn,role,description
处理所有 @ComponentScan 注解,最终创建所有注解类的beanDefintion
处理所有@Import 注解,过程与处理@ComponentScan相似
处理 @ImportResource注解,处理加载xml配置文件
收集所有@Bean 的方法
把收集到的方法或接口,注入到configuration class
ConfigurationClassPostProcessor实现接口方法:processConfigBeanDefinitions(BeanDefinitionRegistry ),其作用是从配置类里面派生更多的bean
核心流程。通过SourceClass的注解,方法,xml等完成创建一个配置类,其过程会反复调用,最终会创建SourceClass里,含有注解的类的beanDefintion
寻找实现了PriorityOrdered.class 的BeanDefinitionRegistryPostProcessor
寻找实现了Ordered.class 的BeanDefinitionRegistryPostProcessor,执行实现类invokeBeanDefinitionRegistryPostProcessors方法
最好寻找所有BeanDefinitionRegistryPostProcessors的实现类,执行invokeBeanDefinitionRegistryPostProcessors方法
Invoke BeanDefinitionRegistryPostProcessors
概述: 因为BeanDefinitionRegistryPostProcessor类 扩展 BeanFactoryPostProcessor类因此BeanDefinitionRegistryPostProcessor的实现类也实现BeanFactoryPostProcessor类的方法postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) ,其核心是:实现应用上下文初始化之后,在beanDefition注册到beanFactory后,对beanDefiotn进行增删改查此时bean还没有实例化。
还是以ConfigurationClassPostProcessor为例子,实现接口postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
过程比较简单,就是跟进bendifition属性元数据,对ConfigurationClass用ConfigurationClassEnhancer做增强处理
查找实现BeanFactoryPostProcessor 的 bean
过滤已经处理过的beanFactoryPostProcessor例如上述的ConfigurationClassPostProcessor
invoke postProcessBeanFactory
invokeBeanFactoryPostProcessors(beanFactory)实例化所有已注册BeanFactoryPostProcessor的bean
过程与上述Invoke BeanDefinitionRegistryPostProcessors,invoke postProcessBeanFactory类似
添加BeanPostProcessorChecker 到 beanFactroy 的bean处理器(BeanPostProcessor)BeanPostProcessorChecker用于bean实例化后的日志打印,和判断是否基础设施bean
在实例化的过程中,bean处理器会调用实现其父类接口(BeanPostProcessor.class)的方法postProcessBeforeInitializationpostProcessAfterInitialization
遍历postProcessorNames,按照bean处理器实现类是否也实现PriorityOrdered,Ordered,无实现(常规)的顺序收集到对应的bean处理器集合,此过程会同时实例化bean处理器,加入到IOC容器。并且判断是否实现MergedBeanDefinitionPostProcessor,并把实现了的加入对应的internal bean处理器集合。
ApplicationListenerDetector 赋值当前应用上下文
registerBeanPostProcessors(beanFactory);实例化Bean处理器
initMessageSource()
initApplicationEventMulticaster()
调用父类GenericWebApplicationContext onRefresh 方法进行web应用的主题资源初始化 initThemeSource
从上下文获取webService,servletContext
如果都为空,走创建webService流程
从beanFactory的BeanDefitionMaps获取ServletWebServerFactory的定义是tomcatServletWebServerFactory,然后调用工厂执行getBean方法,创建TomcatServletWebServerFactory对象
调用getWebServerFactory()获取ServletWebServerFactory
TomcatServletWebServerFactory.getWebServer()作用是启动tomcat服务
createWebServer()
getBeanFactory().registerSingleton(\"webServerGracefulShutdown\
getBeanFactory().registerSingleton(\"webServerStartStop\
initPropertySources
onRefresh()初始化应用上下文特殊的bean,这个方法给子类实现这里继续用AnnotationConfigServletWebServerApplicationContext 为例子
注册创建优雅停机对象到IOC容器
创建SmartLifecycle 对象到IOC容器,交给上下文按顺序控制停止或开启服务开启服务会发送ServletWebServerInitializedEvent
对ApplicationServletEnvironment 进行属性设置
获取上下文所有ApplicationListener,使用ApplicationEventMulticaster,并把ApplicationListener加入到ApplicationEventMulticaster的内部类DefaultListenerRetriever属性ApplicationListener集合
获取所有实现ApplicationListener.class 的beanName,并且加入ApplicationEventMulticaster的内部类DefaultListenerRetriever属性applicationListenerBeans集合
发布在prepareRefresh()阶段应用上下文收集的早期应用事件earlyApplicationEvents
registerListeners()
实例化实现ConversionService.class 的bean
为beanFactory 增加addEmbeddedValueResolver例如PropertySourcesPlaceholderConfigurer bean
实例化实现LoadTimeWeaverAware.class 的bean
beanFactory.freezeConfiguration() 冻结beanDefitionMaps
这里是应用上下文beanFactroy的实现类DefaultListableBeanFactory为例子解析
获取beanFactory 所有的beanDefinitionNames 元素
遍历beanDefinitionNames,根据beanName获取RootBeanDefinition
根据RootBeanDefinition 判断bean非抽象,非懒加载,是单例。开始实例化
根据RootBeanDefinition 判断是否工厂bean,如果是走工厂bean实例化流程AbstractBeanFactory.getBean
否则走常规bean实例化 AbstractBeanFactory.getbean
这个是常用扩展点,例如EventListenerMethodProcessor实现SmartInitializingSingleton,完成@EventListener注解方式的事件监听
Spring Cloud Ribbon中,LoadBalancerAutoConfiguration实现SmartInitializingSingleton接口方法对@LoadBalanced注解的RestTemplate对象利用RestTemplateCustomizer进行定制处理
完成实例化后,判断bean是否实现SmartInitializingSingleton.class,是执行afterSingletonsInstantiated实现bean实例化后,执行某些业务。这个阶段特定是IOC容器快要启动完成了
beanFactory.preInstantiateSingletons()beanDefitionMaps 的bean实例化
如果一级缓存的bean实例为空,且bean实例在当前创建过程中,则进入后继流程。否则结束流程,返回为空对象
如果二级缓存的bean实例为非空,则返回bean实例。 如果为空,且允许循环依赖,则继续流程
对singletonObjects加synchronized,且再次从singletonObjects 获取bean实例。因此上游流程判断bean在当前创建中,有可能已经创建完毕,需要再次判断。如果为非空,则结束流程,返回bean实例。否则继续流程
再次从二级缓存earlySingletonObjects获取bean实例,如果非空则结束流程,返回bean实例,否则继续流程
Object sharedInstance = getSingleton(beanName)获取bean实例,也可能获取FactoryBean
String currentlyCreatedBean = this.currentlyCreatedBean.get()
判断beanName是否FactoryBeanName(beanName以&开头),如果是FactoryBeanName但又不是FactoryBean实例,则抛异常。否则直接返回入参bean实例(符合FactoryBeanName的FactoryBean实例)
上游判断beanName已经不是FactoryBeanName,再判断是否非FactoryBean实例,符合则直接返回bean实例(不符合FactoryBeanName的常规bean实例)
因此得到了不符合FactoryBeanName的FactoryBean实例(例如org.mybatis.spring.mapper.MapperFactoryBean)
判断入参RootBeanDefinition mbd是否为空,是则证明已经创建FactoryBean对象,直接从应用上下文属性BeanFactory的父类FactoryBeanRegistrySupport属性factoryBeanObjectCache获取对,对象不为空即返回。否则继续流程
把入参bean实例强转FactoryBean
如果mbd为空,通过getMergedLocalBeanDefinition获取mdb
通过mdb判断是否后置处理shouldPostProcess
对整个singletonObjects对象加锁synchronized
从factoryBeanObjectCache.get(beanName)获取对象bean对象
如果bean对象不为空,直接返回
如果alreadyThere 不为空(证明已经做了后置处理),直接返回
isSingletonCurrentlyInCreation(beanName)是则直接返回
beforeSingletonCreation(beanName)创建实例预处理,就是往singletonsCurrentlyInCreation加数据
afterSingletonCreation(beanName)创建实例后处理,在singletonsCurrentlyInCreation数据
且需要后置处理
如果alreadyThere为空
FeactoryBean是单例,且singletonObjects存在bean实例。
FeactoryBean不是单例,或者singletonObjects不存在bean实例。
就是在Factory.getObject
创建FeactoryBean
如果sharedInstance 不为空
isPrototypeCurrentlyInCreation(beanName)如果是一个属性bean,则抛异常。多半在循环依赖中出现
判断是否有父类工厂,如果有则执行父类工厂方法getBean并返回
如果需要标记已创建缓存,这执行markBeanAsCreated(String beanName)
设置beanCreation 实例化start
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName)根据BeanName获取RootBeanDefinition
String[] dependsOn = mbd.getDependsOn();获取bean的依赖
使用依赖的beanName 执行getBean(dep),doGetBean(dep)。先创建依赖的bean
完成依赖的bean创建(如果有的话),继续执行原来的bean创建
synchronized (this.singletonObjects)
从一级缓存singletonObjects,获取beanName的bean实例,如果非空,则马上返回。否则继续流程
加入当前创建缓存singletonsCurrentlyInCreation,目的是解决单例模式下的循环依赖
singletonObject = singletonFactory.getObject(),实际是子类DefaultListableBeanFactory的createBean方法
在factoryBeanInstanceCache 获取或直接创建bean包装器BeanWrapper(BeanWrapper继承ConfigurablePropertyAccessor)
用bean包装器实例化被包装的bean(此时只是实例化,bean的属性都为null,半成品)并判断bean是单例且允许循环依赖,且在创建过程中。则调用ObjectFactory的匿名内部方法getEarlyBeanReference,获取objectFactory加入第三级工厂缓存singletonFactories
AbstractBeanFactory.dogetBean()先创建需要依赖注入的对象B,执行doGetBean方法
AutowiredAnnotationBeanPostProcessor#AutowiredMethodElement.inject()
AutowiredAnnotationBeanPostProcessor此实现类类实现依赖注入。假设B注入A,A注入B,A先实例化
主要遍历InstantiationAwareBeanPostProcessor的实现类,调用实现类方法postProcessProperties对beanName做动态代理,autowired等属性操作
invokeAwareMethods各种Aware的实例bean处理
invokeInitMethodsInitializingBean的实例bean处理
applyBeanPostProcessorsAfterInitializationBean完成实例化的后置处理
如果是提前暴露的bean,且二级缓存不为空,检查包装的原始bean和初始化完成的exposedObject是否一致
如果不一致,判断beanName是否已经创建(doGetBean时候,如果发现bean不存在,会走创建流程,这时执行markBeanAsCreated)。意思是检查前后的bean是否一致。如果不一致,则证明其它的bean使用了不是最终版本的,这时候要抛异常BeanCurrentlyInCreationException。这个也是为什么要使用三级缓存而不是二级缓存的原因
删除singletonsCurrentlyInCreation
把createBean的 返回加入级缓存singletonObjects
创建单例bean
创建Prototype bean,同样调用子类方法createBean
如果sharedInstance 为空
AbstractBeanFactory.doGetBeanSpring真正干活的都有一个do字
单独说一下核心流程AbstractBeanFactory.getBean(String name)
finishBeanFactoryInitialization(beanFactory)遍历上下文beanFactory的beanDefitionMaps,对所有非抽象,非懒加载,单例的bean进行实例化
clearResourceCaches();
initLifecycleProcessor()
getLifecycleProcessor().onRefresh()
publishEvent(new ContextRefreshedEvent(this))
finishRefresh()
清除DefaultResourceLoader的resourceCaches缓存因为此时已经有完整的beanDefiniton
使用DefaultLifecycleProcessor 初始化应用上下文的生命周期管理器this.lifecycleProcessor,并注册为单例
实现了Lifecycle的bean,执行start方法,并将DefaultLifecycleProcessor的running状态设置为true。
发布事件ContextRefreshedEvent,很重要,标志着上下文刷新执行完毕
ReflectionUtils.clearCache()
AnnotationUtils.clearCache()
ResolvableType.clearCache()
CachedIntrospectionResults.clearClassLoader(getClassLoader())
resetCommonCaches()
清理反射中缓存的方法和字段信息
清理注解缓存的信息
清理解析类型相关的缓存信息
清理类加载器相关的信息
refresh(); springboot启动流程中最主要复杂的处理方法
通知父类刷新内部工作,其实没做什么,就是返回了beanFactroy。并设置了beanFactory的serializationId,即spring.application.name 或默认配置application
作用跟beanPostProcessors类似,对注册了BeanDefinitionRegistryPostProcessors,BeanFactoryPostProcessor 的postProcessorBean,会执行doGetBean 方法,生成对象到ioc容器中的singletonObjects。整个过程中,postProcessorBean会按照是否继承PriorityOrdered,Ordered和无的排序,先后执行父类的invokeBeanDefinitionRegistryPostProcessors方法,invokeBeanFactoryPostProcessor的方法,对持有它的bean进行在注册beanFatcoty前和后的beanDefition属性修改。例如BeanDefinitionRegistryPostProcessors的实现类ConfigurationClassPostProcessor(同时又实现了PriorityOrdered)对持有Configuration.class(@Configuration)的bean,例如各种配置类及其上级持有的类(@Component,@SpringBootApplication注解在应用启动类),全部加入到beanFactory的beanDefitionMaps。 因此,整个过程的核心,就是加载项目各种bean 到beanDefitionMaps beanDefition,以待实例化
实例化各种bean处理器,并加入到应用上下文中beanFactory的beanPostProcessors
处理国际化
初始化应用上下文的ApplicationEventMulticaster,如果上下文没有定义类型,则默认使用SimpleApplicationEventMulticaster初始化
注册所有ApplicationListener 到ApplicationEventMulticaster,并广播earlyApplicationEvents
遍历上下文beanFactory的beanDefitionMaps,对所有非抽象,非懒加载,单例的bean进行实例化。这里的核心流程是getBean,spring 使用了三级缓存,解决循环依赖
刷新应用上下文,注册生命周期管理器,启动流程发布最后一次事件ContextRefreshedEvent
清理公共缓存信息
listeners.started(context);
实现ApplicationRunner的bean
实现CommandLineRunner的bean
listeners.running(context)
return context
执行run方法
创建启动上下文对象,即spring 根容器
设置无头模式,服务端应用不需要链接显示器,鼠标,键盘等硬件,依然可以运行
监听SA实例执行run方法,处理应用上下文创建之前的业务
初始化应用参数
包装PropertySource以及配置文件数据,放在ConfigurableEnvironment中实现定制配置应用运行环境
获取Banner图,并且在控制台打印
确认使用哪种应用配置上下文,并对其属性进行初始化,如beanFactory,bean注册器等。又因为应用配置上下文有大量父类关系,因此初始化过程中其层级的父类也初始化,即初始化IOC容器
设置应用启动状态
应用上下文准备工作。所有应用上下文初始化器初始化,通知所有应用运行监听器上下文就绪事件.加载应用启动类到上下文属性beanFactory里的属性beanDefitionMaps
应用上下文完成刷新后置处理。这里的子类没有实现方法
触发SpringApplicationRunListeners 集合元素发送应用上下文开启完成事件
触发SpringApplicationRunListeners 集合元素发送应用上下文就绪事件
返回应用上下文
ApplicationRunner/CommandLineRunner 执行器,spring扩展点。应用上下文完成直接出发业务代码。两个执行器只有参数类型不一样
作用:再spring容器初始化之前,初始化ConfigurableApplicationContext 对上下文环境作一些操作,如运行环境属性注册、激活配置文件。
void initialize(C applicationContext)
接口方法
Spring SPI: 在spring.factories 加入映射
SpringApplication#addInitializers
applicaiton.properties
实现方式:
初始化时机:SpringApplication实例化时候
执行时机:springApplication实例执行run方法的prepareContext方法,执行applyInitializers(context)
ContextIdApplicationContextInitializer
SharedMetadataReaderFactoryContextInitializer
DelegatingApplicationContextInitializer
。。。。。。。。。。
内置实现类见SpringApplication属性initializers
ApplicationContextInitializer
作用:容器级后置处理器,在所有的BeanDefinition加载完成之后,Bean真正被实例化之前,进行属性修改。 或进行复杂的业务,例如动态注册自己的beanDefinition,可以加载classpath之外的bean
postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
实现方式: IOC容器内使用,@Component
执行时机:ioc容器初始化之后 ,SptingApplication实例refresh() 阶段。方法invokeBeanFactoryPostProcessors()中执行
ConfigurationClassPostProcessor
内置实现类
BeanDefinitionRegistryPostProcessor
作用与BeanDefinitionRegistryPostProcessor一样,BeanDefinitionRegistryPostProcessor是继承BeanFactoryPostProcessor。执行流程在BeanDefinitionRegistryPostProcessor触发之后
postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
官方建议 BeanDefinitionRegistryPostProcessor 在所有常规bean definitions加载后,用于新增额外的bean definitions
官方建议 BeanFactoryPostProcessor 用于修改bean definitions
区别
BeanFactoryPostProcessor
T getObject()
Class<?> getObjectType()
default boolean isSingleton()
继承FactoryBean,实现接口方法
对FactoryBean 注解@Component(\"beanName\"),托管给spring容器,创建对beanName实例化的工厂bean
执行阶段:AbstractBeanFactory#doGetBean--->#getObjectForBeanInstance--->FactoryBeanRegistrySupport#getObjectFromFactoryBean
实现方式
内置实现类: 内置70多个FactoryBean的实现
FactoryBean
作用:继承BeanPostProcessor,对bean实例化过程中做后置业务处理
执行阶段:SpirngApplication实例refresh的最后阶段,在方法finishBeanFactoryInitialization -> beanFactory.preInstantiateSingletons()
接 口 方 法(执行顺序排列)
AutowiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
InstantiationAwareBeanPostProcessor
作用:同样继承BeanPostProcessor和InstantiationAwareBeanPostProcessor,做bean后置业务操作。实际业务场景开发使用不多,主要在Spring内部应用
接口方法及执行时机
实现方式: IOC容器内使用,@Component
AnnotationAwareAspectJAutoProxyCreator创建代理对象使用
SmartInstantiationAwareBeanPostProcessor
作用: 可以获取系统所有Environment参数设置,比较少用。spring内部都可以通过注入的方式来直接获得
执行阶段: springApplication实例 refresh() --》invokeBeanFactoryPostProcessors(beanFactory)/finishBeanFactoryInitialization(beanFactory),具体哪个阶段执行取决于实现了BeanFactoryPostProcessor还是BeanPostProcessor
PropertySourcesPlaceholderConfigurer
EnvironmentAware
作用:StringValueResolver的一个扩展类, StringValueResolver用于获取基于 String类型的properties的变量,一般用@Value的方式也可以获取。
DefaultFormattingConversionService
WebConversionService
RequestMappingHandlerMapping
EmbeddedValueResolverAware
作用:用于获取ResourceLoader,通过ResouceLoader获取classpath内所有的资源对象
TomcatServletWebServerFactory
WebMvcAutoConfiguration
ResourceLoaderAware
作用:用于获取ApplicationEventPublisher,用来发布事件, 也可以通过spring注入的方式来获得此对象
无内置实现类
创建Event类扩展ApplicationEvent,构建Event事件要素
Event
创建EventPublisher类实现接口ApplicationEventPublisherAware,EventPublisher有类属性ApplicationEventPublisher,并用@Component给IOC容器托管EventPublisher 实例化时候会触发后置处理器ApplicationContextAwareProcessor, 执行setApplicationEventPublisher,把applicationContext设置到EventPublisher的属性ApplicationEventPublisher。现在EventPublisher类有了applicationEventPublisher.publishEvent功能,可以把EventPublisher注入到需要的服务使用事件发布功能。
EventPublisher
创建ApplicationListener类实现ApplicationListener<Event>,覆盖父类方法onApplicationEvent,并托管到IOC容器。完成自动监听
创建ApplicationListener类,托管到IOC容器。新增void方法,入参为Event。方法加上@EventListener,完成自动监听
ApplicationListener
这个要结合ApplicationListener来使用。常用于业务监听处理。举个简单的例子
ApplicationEventPublisherAware
作用:获取MessageSource的一个扩展类,做国际化处理
执行阶段: springApplication实例 refresh() --》finishBeanFactoryInitialization(beanFactory)
MessageSourceAware
作用,获取ApplicationStartup 类,可以标记应用启动期间的步骤
ApplicationStartupAware
作用:ApplicationContext的一个扩展类,常用于手动获取上下文里注册的bean。
EventListenerMethodProcessor
ConfigurationPropertiesBindingPostProcessor
DispatcherServlet
ApplicationContextAware
不是扩展点,是一个特殊的BeanPostProcessor,内置对各种Aware bean实现类进行属性设置。如:最熟悉的ApplicationContextAware的实现类, setApplicationContext 就在这里后置处理,把上文contex设置到实现类的类变量context
ApplicationContextAwareProcessor
执行时机:@PostConstruct方法,在其所在的bean执行 postProcessBeforeInitialization之后,(如果bean同时实现了InitializingBean,InitializingBean.afterPropertiesSet 之前执行)执行postProcessAfterInitialization 之前。
@PostConstruct
相当于init-method,但执行时机早于init-method,实现自定义初始化操作
方法 afterPropertiesSet()
执行时机:在其所在的bean执行 postProcessBeforeInitialization之后,postProcessAfterInitialization 之前。
InitializingBean
作用,所有bean完成完全实例化后,做业务定制
执行时机,在refreshContext(context)阶段最后执行
TestSmartInitializingSingleton
作用:热点数据的预加载、清除临时文件、读取自定义配置信息等
ApplicationRunner run(ApplicationArguments args)
CommandLineRunner run(String... args)
方法
CommandLineRunner和ApplicationRunner
实现DisposableBean的类,实现destroy()方法。当此bean对象被销毁时候执行。
DisposableBean
spring扩展点(按启动时序说明)
0 条评论
回复 删除
下一页