SpringApplication.run(xxx.class, args)背后的东东——整体脉络
从spring到springmvc,再到springboot、springcloud,应用程序api开发调用方面都已经非常熟悉,但对spring背后的扩展机制:为何一个简单的main方法可以实现这么强大的功能,以及与第三方应用如何完美集成?带着这些疑问,了解下springboot背后的整体脉络。
大家都知道,对spring的扩展一般有三种方式:@import注解,实现ImportSeletor,以及实现ImportBeanDefinitionRegistrar接口,所以其实主要搞明白springboot底层是如何支持这三种方式就可以了。
首先,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整合的。
SpringApplication.run(xxx.class, args)背后的东东——整体脉络的更多相关文章
- Spring boot 源码分析(一)SpringApplication.run(上)
SpringApplication.run(Main.class, args); 从这个方法开始讲吧: public static ConfigurableApplicationContext run ...
- 现象:SpringApplication.run后面的语句未执行
下面的两种情况下,红色的log.info中的内容一直没有执行,和预期不符. 看来,需要在@PostConstruct修饰的函数.CommandLineRunner的run方法中调用 另外的线程 来执行 ...
- 011-Spring Boot 运行流程分析SpringApplication.run
一.程序入口 1.1.静态方法 //直接调用run方法 ConfigurableApplicationContext context = SpringApplication.run(App.class ...
- SpringApplication.run 做了哪些事?
SpringApplication.run一共做了两件事,分别是 创建SpringApplication对象 利用创建好的SpringApplication对象,调用run方法论 结论: 面试官: 我 ...
- SpringApplication.run
SpringApplication.run一共做了两件事,分别是 创建SpringApplication对象 利用创建好的SpringApplication对象,调用run方法 1.创建SpringA ...
- 三面面试官:运行 npm run xxx 的时候发生了什么?
事情是这样的,直接开讲 面试官:npm run xxx的时候,发生了什么?讲的越详细越好. 我(心想,简单啊): 首先,DNS 解析,将域名解析成 IP 地址,然后 TCP 连接,TCP 三次握手.. ...
- JSNI GWT中的东东
二.JavaScript Native InterfaceJavaScript本地接口JSNI.1)声明一个本地方法在JSNI中声明一个本地方法时,使用Java的标准native关键字,就像在JNI( ...
- [巩固C#] 一、特性是什么东东
阅读目录 关闭 前言 特性是什么? 那么什么是“元数据”? 特性到底是什么? 我们自定义一个特性玩玩 什么是命名参数? 我们来继续要看看AttributeUsage(这个描... 自定义特性可 ...
- C++ 中可调用的且有函数功能的东东
第一个:函数 其实函数在声明的时候都有个名字: 这个名字可以看作是是指针,将其直接赋值给函数指针 也可以看作是可取指的对其& 再赋值给函数指针 第二个:函数指针 通过其被赋值的方式 ...
随机推荐
- 学习fastapi middleware 源码调用顺序
请求流程如图 本次学到的新东西: functools.partial 可以代码重用 用于在哪些通用的方法上加上更多的参数 try: finally可以当go的defer用 即使return后 fina ...
- BeautifulSoup使用手册(查询篇)
目录 开始使用呢 解析器 四种对象 tag对象 标签名(name) 属性值(Attributes) 多值属性 内容 Comment对象 prettify()方法 find_all方法 contents ...
- [Vue warn]: Error in render: "TypeError: Cannot read property 'matched' of undefined" found in <App> at src/App.vue
当用Vue模块化开发时,输入 http://localhost:8080 页面没有显示,首先按F12,检查是否有如下错误 话不多说,直接看下面: 解决方法1 如果是上面出的问题,以后就要注意了哦, ...
- P 3396 哈希冲突 根号分治
Link 据说这是一道论文题????.具体论文好像是 集训队论文<根号算法--不只是分块> 根号分治的裸题. 首先我们考虑暴力怎么打. 先预处理出每个模数的答案,之后再 O(1) 的回答, ...
- Linux系统编程—有名管道
▋****1. 管道的概念 管道,又名「无名管理」,或「匿名管道」,管道是一种非常基本,也是使用非常频繁的IPC方式. 1.1 管道本质 管道的本质也是一种文件,不过是伪文件,实际上是一块内核缓冲区, ...
- Windows7 提示“无法访问您可能没有权限使用网络资源”的解决办法
大家经常会碰到,电脑A(Windows7)访问局域网打印机的时候出现提示"无法访问你可能没有权限使用网络资源",导致无法正常使用打印机. 那么出现这种情况该如何解决呢? 解决方法: ...
- synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性
synchronized.volatile区别.synchronized锁粒度 synchronized synchronized是Java中的关键字,是一种同步锁.有以下几种用法: 用法 1.修饰方 ...
- python中input()函数与print()函数
一.input()函数详解 二.print()函数详解 三.类型转换
- 题解:HDU 6598
题解:HDU 6598 Description Now, Bob is playing an interesting game in which he is a general of a harmon ...
- 【不知道怎么分类】CF 819B Mister B and PR Shifts
题目内容 洛谷链接 定义一个全排列\(p_i\)的偏移值为\(\sum_{i=1}^{n}|p[i]-i|\). 给你一个全排列,你可以从后面拿\(k\in[0,n-1]\)个数放在前面,使得该全排列 ...