全球热点评!spring启动流程 (1) 流程概览
本文将通过阅读AnnotationConfigApplicationContext源码,分析Spring启动流程。
(资料图片)
创建AnnotationConfigApplicationContext
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();applicationContext.register(XxConfig.class);applicationContext.register(YyConfig.class);applicationContext.refresh();XxService xxService = applicationContext.getBean(XxService.class);
核心的启动逻辑都在refresh方法中。
构造方法
public AnnotationConfigApplicationContext() {this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);}
AnnotatedBeanDefinitionReader类
定义了多个register方法,用于向Spring容器注册BeanDefinition。
在创建AnnotatedBeanDefinitionReader时,会向容器注册几个注解驱动处理器:
- org.springframework.context.annotation.internalConfigurationAnnotationProcessor: ConfigurationClassPostProcessor
- BeanFactoryPostProcessor实现,用于解析@Configuration类。
- 按优先级排序,因为在@Configuration类中声明的任何@Bean方法都必须在任何其他BeanFactoryPostProcessor执行之前注册其对应的BeanDefinition。
- org.springframework.context.annotation.internalAutowiredAnnotationProcessor: AutowiredAnnotationBeanPostProcessor
- BeanPostProcessor实现类。
- @Autowired支持处理器。
- org.springframework.context.annotation.internalCommonAnnotationProcessor: CommonAnnotationBeanPostProcessor
- BeanPostProcessor实现类。
- 支持Resource、PostConstruct、PreDestroy等注解。
- org.springframework.context.event.internalEventListenerProcessor: EventListenerMethodProcessor
- org.springframework.context.event.internalEventListenerFactory: DefaultEventListenerFactory
ClassPathBeanDefinitionScanner类
BeanDefinition扫描器,在类路径上检测Bean,并将其注册到Spring容器中。扫描的类是通过类型过滤器检测到的。
refresh方法
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) {// 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();}}}
prepareRefresh方法
Prepare this context for refreshing, setting its startup date and active flag as well as performing any initialization of property sources.
protected void prepareRefresh() {// Switch to active.this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);// Initialize any placeholder property sources in the context environment.// Replace any stub property sources with actual instances.// web相关的ApplicationContext有实现initPropertySources();// Validate that all properties marked as required are resolvable:// see ConfigurablePropertyResolver#setRequiredPropertiesgetEnvironment().validateRequiredProperties();// Store pre-refresh ApplicationListeners...if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);} else {// Reset local application listeners to pre-refresh state.this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}// Allow for the collection of early ApplicationEvents,// to be published once the multicaster is available...this.earlyApplicationEvents = new LinkedHashSet<>();}
obtainFreshBeanFactory方法
Tell the subclass to refresh the internal bean factory.
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();return getBeanFactory();}
由于AnnotationConfigApplicationContext继承了GenericApplicationContext类,所以此处获取到的是DefaultListableBeanFactory对象。
prepareBeanFactory方法
配置BeanFactory的标准上下文,例如上下文的ClassLoader和后置处理器。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context"s class loader etc.beanFactory.setBeanClassLoader(getClassLoader());// Standard implementation of the BeanExpressionResolver interface,// parsing and evaluating Spring EL using Spring"s expression module.beanFactory.setBeanExpressionResolver( new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.// 支持EnvironmentAware, MessageSourceAware, ApplicationContextAware等beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));beanFactory.ignoreDependencyInterface(EnvironmentAware.class);beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// ApplicationListenerDetector处理器自动将ApplicationListener类型Bean添加容器beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// 注册env beanif (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {beanFactory .registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}}
postProcessBeanFactory方法
Modify the application context"s internal bean factory after its standard initialization. All bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for registering special BeanPostProcessors etc in certain ApplicationContext implementations.
在标准初始化之后修改ApplicationContext的内部bean工厂。所有的BeanDefinition都将被加载,但还没有任何Bean被实例化。这允许在某些ApplicationContext实现中注册特殊的BeanPostProcessors等。
invokeBeanFactoryPostProcessors方法
实例化并调用注册的所有BeanFactoryPostProcessor,如果指定顺序则按照顺序调用,必须在单例实例化之前调用。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 调用BeanFactoryPostProcessorsPostProcessorRegistrationDelegate .invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}}
调用BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor。
registerBeanPostProcessors方法
实例化并注册所有BeanPostProcessor,如果指定顺序则按照顺序注册,必须在应用Bean实例化之前调用。
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);}
把BeanPostProcessor实例添加到beanPostProcessors中:
- 从容器获取所有的BeanPostProcessor Bean
- 按照以下顺序注册:实现了PriorityOrdered接口、实现了Ordered接口、普通BeanPostProcessor、实现MergedBeanDefinitionPostProcessor接口
private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List postProcessors) {for (BeanPostProcessor postProcessor : postProcessors) {beanFactory.addBeanPostProcessor(postProcessor);}}
initMessageSource方法
国际化。
protected void initMessageSource() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);// Make MessageSource aware of parent MessageSource.if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;if (hms.getParentMessageSource() == null) {// Only set parent context as parent MessageSource if no parent MessageSource// registered already.hms.setParentMessageSource(getInternalParentMessageSource());}}} else {// Use empty MessageSource to be able to accept getMessage calls.DelegatingMessageSource dms = new DelegatingMessageSource();dms.setParentMessageSource(getInternalParentMessageSource());this.messageSource = dms;beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);}}
initApplicationEventMulticaster方法
初始化ApplicationEventMultimaster,如果Context中未定义,则使用SimpleApplicationEventMultimaster。
protected void initApplicationEventMulticaster() {ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {this.applicationEventMulticaster = beanFactory.getBean( APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);} else {this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);beanFactory.registerSingleton( APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);}}
onRefresh方法
可以重写的模板方法,以添加指定的刷新逻辑。在初始化特殊Bean时调用,在实例化单例之前调用。
默认什么都不做。
SpringBoot中的ServletWebServerApplicationContext实现类在这个阶段创建WebServer。
registerListeners方法
添加实现ApplicationListener的Bean作为侦听器。不会影响其他侦听器,这些侦听器可以在不使用Bean的情况下添加。
finishBeanFactoryInitialization方法
完成Bean工厂的初始化,初始化所有剩余的单例Bean。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// Initialize conversion service for this context.if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}// Register a default embedded value resolver if no bean post-processor// (such as a PropertyPlaceholderConfigurer bean) registered any before:// at this point, primarily for resolution in annotation attribute values.if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));}// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// Stop using the temporary ClassLoader for type matching.beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes.beanFactory.freezeConfiguration();// Instantiate all remaining (non-lazy-init) singletons.beanFactory.preInstantiateSingletons();}
finishRefresh方法
完成刷新工作,调用LifecycleProcessor的onRefresh()方法并发布ContextRefreshedEvent事件。
protected void finishRefresh() {// Clear context-level resource caches (such as ASM metadata from scanning).clearResourceCaches();// Initialize lifecycle processor for this context.initLifecycleProcessor();// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();// Publish the final event.publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this);}
启动流程
- 创建AnnotationConfigApplicationContext对象
- 创建AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner
- 向容器注册几个注解驱动处理器:ConfigurationClassPostProcessor, AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor等
- 调用applicationContext.register(XxConfig.class)注册配置类
- 调用refresh()方法:
- prepareRefresh方法准备工作:初始化PropertySources、validateRequiredProperties等
- Refresh the internal beanFactory
- 配置BeanFactory的标准上下文,例如上下文的ClassLoader和后置处理器
- 实例化并调用注册的所有BeanFactoryPostProcessor,如果指定顺序则按照顺序调用,必须在单例实例化之前调用
- 实例化并注册所有BeanPostProcessor,如果指定顺序则按照顺序注册,必须在应用Bean实例化之前调用
- 初始化MessageSource
- 初始化ApplicationEventMultimaster,如果Context中未定义,则使用SimpleApplicationEventMultimaster
- onRefresh方法,SpringBoot中的ServletWebServerApplicationContext实现类在这个阶段创建WebServer
- 添加实现ApplicationListener的Bean作为侦听器
- 完成Bean工厂的初始化,初始化所有剩余的单例Bean
- 完成刷新工作,调用LifecycleProcessor的onRefresh()方法并发布ContextRefreshedEvent事件
关键词:
您可能也感兴趣:
为您推荐
视讯!远方信息:副总经理郭志军拟减持股份
狗粮!皮蓬前妻与乔丹儿子海边度假拥吻,拉尔萨西语示爱:我太爱你!|信息
世界快资讯丨大连灵活就业人员社保缴费标准2023年公布
排行
最近更新
- 全球热点评!spring启动流程 (1) 流程概览
- 百事通!县实验中学经典朗诵《满江红》荣获市级一等奖
- 用匠心坚守金融服务初心
- 《经济安全蓝皮书 中国产业链供应链安全发展报告(2022~2023...
- 注册网站需要什么?注册网站流程和费用
- 做短视频素材哪里找?短视频素材获取渠道和注意事项
- 天天微动态丨光威复材:T1100级碳纤维产品已形成验证性收入
- 全球最资讯丨荷兰强降雨造成多地鱼类大量死亡
- 今日热文:如何调节台式电脑屏幕亮度用键盘(如何调节台式电...
- 《空之要塞启航》春节游园会玩法攻略 环球观察
- 世界今热点:【直播预告】书记、县长挂帅督战 山区教育“...
- 当前快报:新疆轮台县:为棉花管理“植”入智慧“基因”
- 滚动:6月26日数字阅读板块跌幅达6%|天天新要闻
- 化石燃料已至穷途末路?OPEC秘书长:在可预见的未来 石油不可替代
- 从北漂到北青,有归属才能继续奋斗!
- 卸妆油对皮肤有刺激吗?卸妆油对皮肤有什么伤害?_当前观点
- 揭秘毒贩跨省售卖海洛因全流程,买家、卖家均获刑
- 第33个全国节能宣传周将于7月10日启动 简讯
- 中国信通院:1-5月国内市场手机总体出货量累计1.08亿部 同比下降0.7%
- 专精特新中小企业成上市主力军 1至5月上市占比56%
- 四环生物: 江苏四环生物股份有限公司第十届董事会第一次会议...
- 【全球新视野】纳微科技: 您在5月初曾询问该问题,请查阅公...
- 张雨绮高伟光拍“床戏”,只是为这部狗血剧添砖加瓦_资讯
- 安徽:充换电设施纳入房地产规划和验收标准 住宅停车位配建...
- 湖南公布21家备案充电桩运营企业
- AI填报高考志愿不咋靠谱 环球滚动
- 中兴通讯发布动态智能超表面2.0原型机,推动5G-A绿色演进
- 苏州妇科比较好的医院 产后子宫脱垂治疗方法_全球时讯
- 苏州东吴医院妇科 怀孕卵巢囊肿会自己消失吗_当前讯息
- 大金融板块表现低迷 中国银河跌近6%
今日要闻
- 每日关注!房地产及物管行业23年第25周周报:端午节奏影响月末冲量 LPR下调期待后续政策
- 做短视频素材哪里找?短视频素材获取渠道和注意事项
- 湖南张家界太任性!机场就建在风景里,游客直呼“中国最美机场”_当前信息
- 全球最资讯丨女神节祝福语金句
- 献给所有孩子和曾经是孩子的大人,许美达编译版《小王子》出版
- 8岁男童被武术教练殴打致死,涉事俱乐部仅成立2个月,警方通报:系故意伤害案件 全球快播报
- 快手小店怎么找商家货源?有哪些途径?
- IAR 与先楫半导体达成战略合作,全面支持先楫半导体高性能RISC-V MCU开发 世界热推荐
- 鄱阳湖水位今年首次突破14米关口 进入丰水期
- 2023年6月26日脱氧熊果苷价格最新行情预测