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++ 中可调用的且有函数功能的东东
第一个:函数 其实函数在声明的时候都有个名字: 这个名字可以看作是是指针,将其直接赋值给函数指针 也可以看作是可取指的对其& 再赋值给函数指针 第二个:函数指针 通过其被赋值的方式 ...
随机推荐
- google chrome安装非官方市场插件方法
1. 下载 Chrome组策略管理模板"chrome.adm"(下载地址):2. Win+R 打开运行,输入 gpedit.msc,确定:3. 依次展开 本地计算机策略 > ...
- vs code的使用与常用插件和技巧大全总结
vs code的使用与常用插件和技巧大全总结 Author:3# 一个专注于web技术的80后 我不用拼过聪明人,我只需要拼过那些懒人 我就一定会超越大部分人! CSDN@ 极客小俊,CSDN官方首发 ...
- 聊聊经典数据结构HashMap,逐行分析每一个关键点
本文基于JDK-8u261源码分析 本文原创首发于 奇客时间(qiketime) 1 简介 HashMap是一个使用非常频繁的键值对形式的工具类,其使用起来十分方便.但是需要注意的是,HashMap不 ...
- 理解pytorch几个高级选择函数(如gather)
目录 1. 引言 2. 维度的理解 3. gather函数 4. index_select函数 5. masked_select函数 6. nonzero函数 1. 引言 最近在刷开源的Pytor ...
- shiro入门学习--使用MD5和salt进行加密|练气后期
写在前面 在上一篇文章<Shiro入门学习---使用自定义Realm完成认证|练气中期>当中,我们学会了使用自定义Realm实现shiro数据源的切换,我们可以切换成从关系数据库如MySQ ...
- C++ 中explicit的作用
转载:https://www.cnblogs.com/diligenceday/p/5781408.html C++ 中explicit的作用 explicit作用: 在C++中,explicit ...
- Docker安装MongoDB、MySQL、Jenkins、Gitlab、Nginx
Docker安装MongoDB.MySQL.Jenkins.Gitlab.Nginx 安装MongoDB 1. 拉取镜像 $ sudo docker pull mongo 2. 运行镜像 $ sudo ...
- 前端传递的json格式与SpringMVC接收实体类的对应关系
这篇文章主要是帮助刚刚入行的猿猿尽快适应Restful风格的搬砖生活 @RequestBody注解 基本介绍:@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数 ...
- 【idea&spring mvc】搭建简易的spring mvc项目(基于maven)!
一.创建项目 1.打开idea,file--new--project 2.按照步骤①②③④操作 3.输入包名,并点击下一步 4.选择下载包的maven的setting.xml配置路径和包的存放地,然后 ...
- 自定义chrome新标签页
[跳转GitHub] chromeNewTab 自定义chrome新标签页.由于不想发布到chrome应用商店,因此搜了一下不用开发者模式就能用的方法. 使用说明 下载chrome的一个[window ...