逆水行舟用力撑,一篙松劲退千寻。这篇文章主要讲述SpringApplication.run(xxx.class, args)背后的东东——整体脉络相关的知识,希望能为你提供帮助。
从spring到springmvc,再到springboot、springcloud,应用程序api开发调用方面都已经非常熟悉,但对spring背后的扩展机制:为何一个简单的main方法可以实现这么强大的功能,以及与第三方应用如何完美集成?带着这些疑问,了解下springboot背后的整体脉络。
大家都知道,对spring的扩展一般有三种方式:@import注解,实现ImportSeletor,以及实现ImportBeanDefinitionRegistrar接口,所以其实主要搞明白springboot底层是如何支持这三种方式就可以了。
【SpringApplication.run(xxx.class, args)背后的东东——整体脉络】
首先,run方法执行时,会实例化spring容器,其实根据不同的环境实例化不同的容器类
context = createApplicationContext();
servlet环境是实例化AnnotationConfigServletWebServerApplicationContext类,这里最重要是注册一些内置的BeanDefinitionRegistryPostProcessor(BeanFactoryPostProcessor的子接口),其中就包含重要ConfigurationClassPostProcessor,spring还特意为这种beandefinition取了beanname,如:org.springframework.context.annotation.internalConfigurationAnnotationProcessor。这里有必要解释下beandefinition,这个类个人认为是spring最重要的,spring容器管理的对象是我们创建的普通bean,但spring在创建之前,对这种bean用beandefinition进行了包装和描述,进而可以在不同的扩展点去扩展bean的功能,底层是通过实现beanpostprocessor接口,同理咱们还可以实现beanfactorypostprocessor接口去扩展beandefinition,这也是spring设计的巧妙之处。
实例化工作完成之后会调用spring刷新容器的方法
org.springframework.context.support.AbstractApplicationContext#refresh
接下来工作其实无非就是在哪个时机对刚刚spring进行注册的beanfactorypostprocessor进行调用的问题,spring底层是委托PostProcessorRegistrationDelegate进行处理的。
org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
最后就是回调ConfigurationClassPostProcessor等方法了
org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
@Import就是通过以下方法处理,将其配置信息解析出来
org.springframework.context.annotation.ConfigurationClassParser#processImports
最后,将其注册到spring的BeanDefinitionRegistry中,整个扩展过程就完成了,剩下的就是spring如何根据beandefinition去实例化bean了。
org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#registerBeanDefinitionForImportedConfigurationClass
回到最开始的问题,spring既然可以通过BeanDefinitionRegistryPostProcessor去动态的扩展beandefinition来实例化bean,那我们就可以利用这个扩展机制来集成第三方的工具到spring中,利用容器来管理这些bean,比如mybatis就是通过MapperScannerConfigurer来和spring整合的。
推荐阅读
- springboot[2.3.4.RELEASE]application.properties常用配置
- Android | 零代码快速集成AGC崩溃服务
- android 二级列表 二级目录
- leetcode407 Trapping rain water II
- vue+uni-app商城实战 | 第一篇(有来小店微信小程序快速开发接入Spring Cloud OAuth2认证中心完成授权登录)
- cnpm : 无法加载文件 C:UsersadminAppDataRoamingpmcnpm.ps1,因为在此系统上禁止运行脚本。有关详细信息 hbuilderx
- 用华为HMS ML kit人体骨骼识别技术,Android快速实现人体姿势动作抓拍
- 了解Android_04之EditText标签
- 在Android中如果在非UI线程更新UI会抛出异常