Spring源码解读
文章目录
1. Bean的创建生命周期
Person -> 无参的构造方法 -> 普通的对象 -> 依赖注入(属性的赋值)-> 初始化前(@PostConstruct) -> 初始化 - > 初始化后(AOP) -> 代理对象 - > Bean
2.启动扫描源码机制
1.1) 获取到直接配置路径
1.2)判读是否符合Bean的条件
1.3)这里只是把className设置到BeanDefinition中,并没有加载类
1.4)这个是判断是区分独立的类
- 静态的或者是普通的类部类
- 是不是接口是不是抽象类
@Lookup
:每次返回的对象方法都是重新创建的
1.5)做一系列的处理
1.6)检查Spring容器中是否已经存在该beanName,,这个检查机制就是,name存在冲突抛出异常,,扫描多次不注册
3.创建不是懒加载单例Bean
- 如果是
factorybean
那么会创建两个Bean一个是单例池中的bean例外一个是缓存池bean,但是缓存池只有再获取的时候才会创建处于懒加载机制,如果要立即创建的话那么久需要事项SmartFactoryBean
接口
3.1) 获取到BeanDefinition,判断是否是抽象的,如果是抽象的就不创建
3.2)@DependsOn
表示当前beanName所依赖的,当前Bean创建之前dependsOn所依赖的Bean必须已经创建好了。
- 循环依赖的判断
- 如果不是注册到dependOnMap中去
- 然后再去创建Bean
3.3)创建单例bean
-
加载class
-
实例化前
applyBeanPostProcessorsBeforeInstantiation
有返回值—> 直接初始化后操作applyBeanPostProcessorsAfterInitialization
-
实例化 —>
applyMergedBeanDefinitionPostProcessors
(处理BeanDefinition的处理器,,@Autowired
注解有关,内置寻找注入点就是依赖这个完成的)- 在创建一个Bean的过程中,Spring会利用
AutowiredAnnotationBeanPostProcessor
的postProcessMergedBeanDefinition()
找出注入点并缓存,找注入点的流程为:- 遍历当前类的所有的属性字段Field
- 查看字段上是否存在@Autowired、@Value、@Inject中的其中任意一个,存在则认为该字段是一个注入点
- 如果字段是static的,则不进行注入
- 获取@Autowired中的required属性的值
- 将字段信息构造成一个AutowiredFieldElement对象,作为一个注入点对象添加到currElements集合中。
- 遍历当前类的所有方法Method
- 判断当前Method是否是桥接方法,如果是找到原方法
- 查看方法上是否存在@Autowired、@Value、@Inject中的其中任意一个,存在则认为该方法是一个注入点
- 如果方法是static的,则不进行注入
- 获取@Autowired中的required属性的值
- 将方法信息构造成一个AutowiredMethodElement对象,作为一个注入点对象添加到currElements集合中。
- 遍历完当前类的字段和方法后,将遍历父类的,直到没有父类。
- 最后将currElements集合封装成一个InjectionMetadata对象,作为当前Bean对于的注入点集合对象,并缓存。
- 在创建一个Bean的过程中,Spring会利用
-
循环依赖
-
属性填充
- 实例化后
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
- 普通自带的注入
byType
找set方法参数的类型byName
找set方法名字
InstantiationAwareBeanPostProcessor.postProcessProperties
处理@Autowired
注解的注入
- 实例化后
-
初始化
- 初始化回调方法
Aware
- 初始化前,执行带有
@PostConstruct
和@PreDestroy
的方法 - 初始化
- 初始化后
- 初始化回调方法
3.4)创建原型bean
3.5)springmvc里面的作用域bean