参考黑马程序员视频https://www.bilibili.com/video/BV15b4y117RJ?p=143&spm_id_from=pageDriver
理解一些总结概念:
- context就是我们所说的容器,有子容器还有父容器。
- bean之间有依赖关系,这种关系决定了他们的创建顺序。
- context.refresh()方法就是去创建获取bean,实际上调用了getbean方法。
- 有三种scope范围的创建销毁bean,scope实际是决定了什么时候触发创建什么时候销毁。
- prototype(多例)范围的bean需要手动销毁,调用beanfactory的destroy方法,此外多例bean不创建缓存,每次都是创建新的bean对象。
- 注解作用:依赖注入,在某个controller当中修饰某个成员变量,这个成员变量是个类也就是bean。这个被注解修饰的bean可以被AutoAnnotationBeanPostProcessor发现并new出一个bean,AutoAnnotationBeanPostProcessor是识别被@Autowired@Value标注的成员变量并转为injectionMetadata(这里我用目前知识猜测这个类可能是原来数据的子类类似于proxy类的)进行依赖注入。而commonAnnotation则是识别@Resource标注的成员,同样也封装成元素据。
- 可通过不同方式去构造bean(例如autowiredannotation,默认构造)。首先bean在创建的时候,由AutoAnnotationBeanPostProcessor扫描@autowired注解,若没有注解则autoAnnatationBeanPostProcessor扫描唯一的带参构造(唯一是指bean的带参构造是唯一的)完成bean的创建,以上情况都没有,采用默认构造。
- beanpostprocessor叫做"bean后处理器",作用是识别注解并封装为injectionmetadata注解元数据,由注解元数据类完成注入操作。
- bean在要创建时首先会去检查三级缓存,(这其实是解决循环依赖的方法)
- 总体流程:先检查缓存,没有就由AutoAnnatationBeanPostProcessor去检查@Autowired的构造方法(没有就调用默认构造)。之后进行依赖注入(set等操作)AutoAnnatationBeanPostProcessor又会扫描@Autowired以及@Value修饰的成员变量并封装成元数据供这个类使用,之后进行bean的初始化:通过实现aware接口或者是CommonAnnatationBeanPostprocessor扫描@PostConstruct进行初始化。最后进入标记销毁阶段,查看实现了哪些销毁方法或者是销毁接口(DisosableBean或者是AutoCloseable)则标记为可销毁bean在scope的影响下完成对应销毁。
1.创建bean的整体流程
第一阶段
三级缓存解决了循环依赖
第二阶段
先找子容器里面的bean子容器找不到然后找父容器里面的bean。
第三阶段
控制bean的创建顺序(没有显示依赖)
第四阶段
按照scope属性去创建
常见的三种scope的生存范围
第一种:单例范围
refresh开始到close结束。
refresh还是调用了getbean方法
第二种:多例模式bean
只有在调用了容器的getbean方法时才会创建bbean
销毁需要手动调用
第三种request
同样也是在getbean方法的时候进行创建操作
scope总结
prototype就是我们说的多例bean
阶段五 创建bean
创建bean的方式
刚建立的bean需要建立依赖,也就是注入其他bean可以想象springboot注册@Service等等,就可以在本层使用该bean。
优先级越往下越高
之后我们要初始化bean:
1.实现aware接口
2.三种初始化方法
3.创建aop代理
以上初始化方法执行顺序为
aware接口,注解,接口(initializingbean),自定义(beandefinition)
对应下面输出4213
最后需要标记销毁bean
自定义scope包括request等。
第六阶段类型转换