Spring学习记录

Spring学习

Spring学习第一天

  • Spring Bean 创建的过程
    一个对象->通过构造方法->得到一个对象->通过依赖注入进行属性赋值(byType/byName,先通过type找,找到多个在根据name找,如果还是存在多个,则报错)->初始化前->初始化->初始化后(AOP在这个步骤实现)->Bean(如果经过了AOP处理,生成的Bean则是代理Bean)

  • 初始化前,初始化,初始化后的扩展方法

    1. @PostConstruct
    2. InitializationBean
  • 事务失效问题
    事务失效主要看调用标记@Transactional方法是被普通bean调用还是代理bean调用

  • @Configuration的作用
    被此注解标记后,配置类就成为一个代理类,当要创建bean时,会先从spring容器判断是否存在此类,存在则直接返回,不会重复创建。

Spring学习第二天

  • 首先明确一点:
    ApplicationContext ac = new XXXApplicationContext(xxx);
    ac.getbean
    单例,非懒加载的bean在第一行代码中就会创建;反之,在第二行创建

  • 手写spring实现大概步骤

  1. 读取配置,得到扫描路径

  2. 通过类加载器获取路径->转换成File->转换成Class

  3. 通过class.isAnnotationPresent(@Compoment.class) 判断此类是否需要被Spring容器管理

  4. 转换成BeanDifinition,放入Map(避免重复解析)
    以上,就完成了bean的扫描,接下来开始创建bean

  5. 对于单例可以直接通过构造方法创建,放进单例池 ;对于多例,每次getBean的时候都创建
    以上就完成了bean的实例化,接下来实现依赖注入

  6. 通过class.getDeclareFile().isAnnotationPresent(Autowired.class)判断是否需要进行依赖注入

  7. 接下来实现初始化,初始化前,初始化后
    初始化可以使用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源码中
  1. 扫描的过程
  2. 创建单例、非懒加载的bean
  3. @Conditional,@LookUp
  4. SmartInitializingSingle:在所有的单例非懒加载的bean创建完成之后被调动
  5. 并不是所有的bean都是首字母小写
  • 入口
  1. 扫描:ClassPathBeanDefinitionScanner.scan(xxx)
  2. 创建单例、非懒加载的单例bean:
    org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
  • 合并BeanDefinition
    当一个bean存在父子关系时使用

Spring学习第五天

  • 主要学习bean生命周期每个阶段重要的接口
  1. 实例化前 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()

  2. 实例化

  3. MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()

  4. 实例化后 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()

  5. InstantiationAwareBeanPostProcessor.postProcessPropertyValues() // @Autowired,@Resource,@Value就是这个方法里面被解析的
    AutowiredAnnotationBeanPostProcessor,CommonAnnotationBeanPostProcessor

  6. Aware回调 ApplicationContextAwareProcessor

  7. 初始化前

  8. 初始化

  9. 初始化后

Spring学习第六天

主要学习Spring是怎么解决循环依赖
解决Spring循环依赖使用了三级缓存,包括singletonObjects、earlySingletonObjects
、singletorFactories

  • 以A,B出现循环依赖为例

    1. 标记A为创建中
    2. 实例化A(得到原始对象,放入creatingSet中)—>放入三级缓存singleFactories(beanName,()->getEarlyBeanReference(beanName,mbd,bean)); 黑体部分逻辑主要用于判断是否需要AOP,需要则返回代理对象,不需要则返回原始b对象
    3. 填充B(单例池没有—>实例化B)
    4. 填充A(发现creatingSet中有,出现循环依赖)
    5. 去earlySingletonObjects找,没有
    6. 去singletorFactories 找,执行getEarlyBeanReference(beanName,mbd,bean)放入二级缓存(此时放入的还是半成品,还没有经历完整的生命周期)
    7. 填充属性等完整生命周期

    二级缓存的作用和意义:
    作用:存半成品,保存还未经历完整生命周期的对象
    意义:保证单例
    三级缓存的作用和意义:
    作用:保存表达式判断是否需要AOP
    意义:打破循环依赖
    思考: 如果不考虑AOP,那么二级缓存就可以解决循环依赖

Spring学习第七天

主要学习Spring启动过程源码分析

public AnnotationConfigApplicationContext(Class<?>… annotatedClasses) {
this();
register(annotatedClasses);
refresh();
}
对于此方法第一步主要是初始化一些重要的类,做一些提前准备
第二步主要是将配置转换成BeanDefinition,放入beanDefinitionMap

理解refresh()的含义

BeanFactoryPostProcessor:表示BeanFactory的后置处理器,用来对BeanFactory进行加工的
BeanPostProcessor:表示Bean的后置处理器,是用来对Bean进行加工的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值