Spring学习
Spring学习第一天
-
Spring Bean 创建的过程
一个对象->通过构造方法->得到一个对象->通过依赖注入进行属性赋值(byType/byName,先通过type找,找到多个在根据name找,如果还是存在多个,则报错)->初始化前->初始化->初始化后(AOP在这个步骤实现)->Bean(如果经过了AOP处理,生成的Bean则是代理Bean) -
初始化前,初始化,初始化后的扩展方法
- @PostConstruct
- InitializationBean
-
事务失效问题
事务失效主要看调用标记@Transactional方法是被普通bean调用还是代理bean调用 -
@Configuration的作用
被此注解标记后,配置类就成为一个代理类,当要创建bean时,会先从spring容器判断是否存在此类,存在则直接返回,不会重复创建。
Spring学习第二天
-
首先明确一点:
ApplicationContext ac = new XXXApplicationContext(xxx);
ac.getbean
单例,非懒加载的bean在第一行代码中就会创建;反之,在第二行创建 -
手写spring实现大概步骤
-
读取配置,得到扫描路径
-
通过类加载器获取路径->转换成File->转换成Class
-
通过class.isAnnotationPresent(@Compoment.class) 判断此类是否需要被Spring容器管理
-
转换成BeanDifinition,放入Map(避免重复解析)
以上,就完成了bean的扫描,接下来开始创建bean -
对于单例可以直接通过构造方法创建,放进单例池 ;对于多例,每次getBean的时候都创建
以上就完成了bean的实例化,接下来实现依赖注入 -
通过class.getDeclareFile().isAnnotationPresent(Autowired.class)判断是否需要进行依赖注入
-
接下来实现初始化,初始化前,初始化后
初始化可以使用InitializationBean测试
初始化前和初始化后可以使用BeanPostProcessor测试
初始化前可以使用BeanNameAware测试
初始化后可以先使用动态代理实现模拟切面实现
Spring学习第三天
-
创建bean的方式:声明式,编程式
-
几个常用的解析Bean成beanDefinition的类
AnnotatedBeanDefinitionReader/ClassPathXXX 父类 GenericXXX
XmlBeanDefinitionReader -
ApplicationContext与BeanFactory的区别
国际化/资源加载/获取运行时环境/事件发布 -
DefaultListableBeanFactory
-
BeanFactory和FactoryBean的区别
BeanFactory生成的bean是经过了完整的生命周期的,而FactoryBean创建的声明周期只经历了初始化后(考虑到AOP,其他步骤不需要经历是因为自己可以定制化)
2.会创建2个bean,一个是通过@Component创建出来的,放在单例池,一个是getObject方法返回的,放在另外一个缓存里面
3.得到的bean变成getObject返回的bean
Spring学习第四天
- 主要学习spring源码中
- 扫描的过程
- 创建单例、非懒加载的bean
- @Conditional,@LookUp
- SmartInitializingSingle:在所有的单例非懒加载的bean创建完成之后被调动
- 并不是所有的bean都是首字母小写
- 入口
- 扫描:ClassPathBeanDefinitionScanner.scan(xxx)
- 创建单例、非懒加载的单例bean:
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
- 合并BeanDefinition
当一个bean存在父子关系时使用
Spring学习第五天
- 主要学习bean生命周期每个阶段重要的接口
-
实例化前 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
-
实例化
-
MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()
-
实例化后 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()
-
InstantiationAwareBeanPostProcessor.postProcessPropertyValues() // @Autowired,@Resource,@Value就是这个方法里面被解析的
AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor -
Aware回调 ApplicationContextAwareProcessor
-
初始化前
-
初始化
-
初始化后
Spring学习第六天
主要学习Spring是怎么解决循环依赖
解决Spring循环依赖使用了三级缓存,包括singletonObjects、earlySingletonObjects
、singletorFactories
-
以A,B出现循环依赖为例
- 标记A为创建中
- 实例化A(得到原始对象,放入creatingSet中)—>放入三级缓存singleFactories(beanName,()->getEarlyBeanReference(beanName,mbd,bean)); 黑体部分逻辑主要用于判断是否需要AOP,需要则返回代理对象,不需要则返回原始b对象
- 填充B(单例池没有—>实例化B)
- 填充A(发现creatingSet中有,出现循环依赖)
- 去earlySingletonObjects找,没有
- 去singletorFactories 找,执行getEarlyBeanReference(beanName,mbd,bean)放入二级缓存(此时放入的还是半成品,还没有经历完整的生命周期)
- 填充属性等完整生命周期
二级缓存的作用和意义:
作用:存半成品,保存还未经历完整生命周期的对象
意义:保证单例
三级缓存的作用和意义:
作用:保存表达式判断是否需要AOP
意义:打破循环依赖
思考: 如果不考虑AOP,那么二级缓存就可以解决循环依赖
Spring学习第七天
主要学习Spring启动过程源码分析
public AnnotationConfigApplicationContext(Class<?>… annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
对于此方法第一步主要是初始化一些重要的类,做一些提前准备
第二步主要是将配置转换成BeanDefinition,放入beanDefinitionMap
理解refresh()的含义
BeanFactoryPostProcessor:表示BeanFactory的后置处理器,用来对BeanFactory进行加工的
BeanPostProcessor:表示Bean的后置处理器,是用来对Bean进行加工的