SpringBoot源码简要解析
涉及到的注解
@Import
这个注解可以导入相应的组件对象,并且这个注解对应的有三种使用方法
;下面简单举一些例子。
1、直接使用import导入组件类
2、直接使用import导入可选择的组件类
通过import导入一个实现了ImportSelector接口
的类;这个类在重写方法中返回需要放入到容器中的组件的全限定类名
。
如果不存在对应的全限定类名则报错
。
3、直接使用import导入可选择的组件类
通过import导入一个实现了ImportBeanDefinitionRegistrar接口
的类。
重写的方法是一个空返回,但是可以拿到BeanDefinitionRegistry
进行组件的注册。
@Condition
使用的需求是:有的时候我们需要当某一个条件满足的时候才把一些类实例化并 加入到 spring 容器中。
其本质是一个接口;可以自定义进行对应的规则匹配。
proxyBeanMethods属性
该属性是boot2.0以后
的更新,配置在@Configuration中
值为 true
1) Full全配置;每次去调用的时候都会检查容器中是否已经存在这个对象实例,存在就返回
2) 调用CGlib子类代理对象
3) 外部无论对配置类的这个组件注册的方法进行N次调用,返回的都是同一个对象。Spring默认单例
值为false
1) lite轻量配置;跳过检查操作,每次调用都直接调用返回一个新对象
2) 调用对象本身
3) 外部调用其注册组件的方法,返回的是不同对象
• 具体用法:组件中是否需要相互依赖,需要的话保证依赖的是容器中的组件而不是新生成的组件。’
• 解决的问题:组件依赖
依赖管理
• 父工程
1)指定JDK版本,编码集
2)引入配置文件
• 爷爷工程
1) 统一maven版本管理(先进行声明,后统一管理)
- 工程打包。我们在使用某些jar包的时候,只需要对应的场景启动器start即可,引入了场景启动器jar包就会自动导入。因为场景启动器已经帮我们将jar包打包好了,相当于间接依赖这些jar包。
以web场景启动器为例,他会帮我们引入 很多相关的依赖,例如json序列化,内嵌tomcat等等。不会因为少引入某些包而发生错误,并且在SpringBoot的父工程已经进行了jar包的版本统一管理,我们也不需要考虑版本之间的适配和冲突。
但是需要注意,如果SpringBoot官方没有提供场景启动器,自己引入其他插件的场景启动器就需要加上版本号。例如mybatis启动器,durid数据源
等等。
自动装配注解
AutoConfigurationImportSelector
自动配置
1、每个场景启动器的依赖中都会传递一个spring-boot-autuconfig的依赖坐标。
2、我们找到其类,发现有很多的自动配置(configuration文件)
3、但是很多文件都爆红,说明不能用。
4、这些文件都在一个@Conditional的注解下
自定义starter流程
1、新建模块,按照SpringBoot官方要求 XXX-Spring-boot-start
2、在模块中写我们需要的业务代码
3、resources下创建/META-INF/spring.factories
文件内容:
1)配置信息。
2 )org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 要自动加载的类的全限定类名
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.xx.config.MyAutoConfiguration
代码启动
这部分分为两个模块;第一是实例化对象过程
,第二是执行Run方法
实例化对象过程
1、将启动类作为参数传入到run方法中
2、重载到实例化SpringApplication类的方法
3、将类放入到暂存的容器中
DEBUG调试的结果
Run方法
1、只有这个方法是将启动类丢入容器中;其他的方法都是辅助方法或实例化容器的。
2、读取容器中启动类
3、找到启动类并返回
4、接着找到末尾的load
继续委托调用load
然后一直调用自己的load方法进行解析,最终将启动类注入到IOC容器中
到了这一步,就和Spring的注解方式一样了。
内容补充:注解方式IOC的包扫描类注入
1、创建容器类,并传入对应的扫描类
2、实例化对象并注册扫描类到容器中
小细节
这里要注入一个细节,当@ComponentScan标注的类作为参数传入到启动容器中,那么该类不需要加类似@Comment的注解
原因:加上这个注解只是让Spring知道他是一个bean类,要加入到容器中。但是通过这种方式将该Class类传入新建的容器对象中时,已经将其进行了容器注册,所以可以不用加类似@Comment的注解。
Tomcat的启动
当我们一路跟着刷新容器走下来,发现他最后走到了
org.springframework.context.support.AbstractApplicationContext
这个类中的refresh方法上。那么就和我们的Spring对接上了。
看到这个方法的大体类
Spring提供了一个整体的执行流程模板,当我们需要进行扩展启动的时候可以在onRefresh中进行操作