02-Spring源码

2021-02-20  本文已影响0人  安然在路上

春节期间学习的,时间够够的,效率渣渣的,无数次地怀疑自己,最后还是靠抄作业才能解锁下一模块,啊哈哈哈

好吧,感觉这笔记不太好做。。。但是,我是写给自己看的

1.基础

IOC和DI

听到这里的时候,觉得老师太厉害了,在面试的时候我终于能说清这俩词了。
描述的是同一件事(对象实例化以及依赖关系维护),但是角度不同。
IOC:站在对象的角度,对象实例化和管理的权限交给了容器。
描述的是@Service、@Component等做的事情(好像不太对的样子)
DI:站在容器的角度,容器会把对象依赖的其他对象注入给它。比如:A对象需要B,那么使用@Autowired注解,容器会把B对象注入给A。

AOP

连接点joinpoint:方法开始时、结束时、正常运行完毕时、方法异常时
切入点pointcut:指定aop要影响的方法是哪些
advice增强/通知:横切逻辑 + 方位点(加入了横切逻辑的连接点,叫方位点),包括:前置通知、后置通知、异常通知、最终通知、环绕通知

2、手写IOC和AOP

AOP

  1. 数据库事务是connection事务,connection.commit(),connection.rollback。事务控制应该加在service层。
  2. 为了保证同一个service方法使用同一个连接,使用ThreadLocal修饰connection变量。
  3. 将事务控制代码放在 动态代理InvocationHandler的invoke方法中

IOC
1.从xml换成支持注解作业步骤:扫描所有要加到容器的类 -> 循环处理依赖(@Autowired) -> 处理需要用到动态代理的类(@Transactional)
?? 第二步和第三步能换位置吗

3、Spring IOC高级特性

  1. BeanFactory vs ApplicationContext : BeanFactory 是IOC容器的顶层接口。ApplicationContext 是 BeanFactory 的子接口,增加了从XML文件读取、国际化等功能。
  2. @Autowired采取的策略为按照类型注⼊。当⼀个类型有多个bean值的时候,会造成⽆法选择具体注⼊哪⼀个的情况,这时需要配合@Qualifier使⽤。同时使用@Autowired和@Qualifer("beanName")
  3. FactoryBean vs BeanFactory
    BeanFactory
    FactoryBean用来生产某个类型的bean示例,该接口中最重要的方法是getObject,如果是单例的,该对象会被放到单例对象缓存池map中。
    BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的⼀个⼯⼚
  4. 后置处理器
    Spring提供了两种后处理bean的扩展接⼝,分别为 BeanPostProcessor 和BeanFactoryPostProcessor。
    BeanFactoryPostProcessor:简单来说就是获取容器BeanFactory,允许我们在工厂里所有的bean被加载进来后但是还没初始化前,对所有bean的属性进行修改,可以理解为是对beanDefinition进行修改。
    典型应⽤:PropertyPlaceholderConfigurer
    BeanPostProcessor :是针对Bean级别的处理。

Bean生命周期流程

bean的生命周期
  1. 核心接口:
    InitializaingBean 方法:afterPropertiesSet
    BeanPostProcessor 方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
    BeanFactoryPostProcessor 方法 :postProcessBeanFactory
    通过调用栈分析核心方法为refresh()

2、解决循环依赖
单例,且是set注入才有解


循环依赖问题.png

4、 Spring AOP高级特性

  1. 事务的四⼤特性
    原⼦性(Atomicity)原⼦性是指事务是⼀个不可分割的⼯作单位,事务中的操作要么都发⽣,要么都不发⽣。
    从操作的⻆度来描述,事务中的各个操作要么都成功要么都失败
    ⼀致性(Consistency)事务必须使数据库从⼀个⼀致性状态变换到另外⼀个⼀致性状态。例如转账前A有1000,B有1000。转账后A+B也得是2000。
    ⼀致性是从数据的⻆度来说的,(1000,1000)(900,1100),不应该出现(900,1000)
    隔离性(Isolation)事务的隔离性是多个⽤户并发访问数据库时,数据库为每⼀个⽤户开启的事务,每个事务不能被其他事务的操作数据所⼲扰,多个并发事务之间要相互隔离。
    ⽐如:事务1给员⼯涨⼯资2000,但是事务1尚未被提交,员⼯发起事务2查询⼯资,发现⼯资涨了2000块钱,读到了事务1尚未提交的数据(脏读)
    持久性(Durability)
    持久性是指⼀个事务⼀旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发⽣故障也不应该对其有任何影响。

  2. 事务的隔离级别
    不考虑隔离级别,会出现以下错误情况:也即为隔离级别在解决事务并发问题
    脏读:⼀个线程中的事务读到了另外⼀个线程中未提交的数据。
    不可重复读:⼀个线程中的事务读到了另外⼀个线程中已经提交的update的数据(前后内容不⼀样)
    场景: 员⼯A发起事务1,查询⼯资,⼯资为1w,此时事务1尚未关闭财务⼈员发起了事务2,给员⼯A张了2000块钱,并且提交了事务
    员⼯A通过事务1再次发起查询请求,发现⼯资为1.2w,原来读出来1w读不到了,叫做不可重复读
    虚读(幻读):⼀个线程中的事务读到了另外⼀个线程中已经提交的insert或者delete的数据(前后条数不⼀样)
    场景: 事务1查询所有⼯资为1w的员⼯的总数,查询出来了10个⼈,此时事务尚未关闭事务2财务⼈员发起,新来员⼯,⼯资1w,向表中插⼊了2条数据,并且提交了事务事务1再次查询⼯资为1w的员⼯个数,发现有12个⼈

数据库共定义了四种隔离级别:
Serializable(串⾏化):可避免脏读、不可重复读、虚读情况的发⽣。(串⾏化)最⾼Repeatable read(可重复读):可避免脏读、不可重复读情况的发⽣。(幻读有可能发⽣)第⼆该机制下会对要update的⾏进⾏加锁
Read committed(读已提交):可避免脏读情况发⽣。不可重复读和幻读⼀定会发⽣。第三Read uncommitted(读未提交):最低级别,以上情况均⽆法保证。(读未提交)最低

注意:级别依次升⾼,效率依次降低
MySQL的默认隔离级别是:REPEATABLE READ

  1. 事务的传播⾏为
    事务往往在service层进⾏控制,如果出现service层⽅法A调⽤了另外⼀个service层⽅法B,A和B⽅法本身都已经被添加了事务控制,那么A调⽤B的时候,就需要进⾏事务的⼀些协商,这就叫做事务的传播⾏为。
    A调⽤B,我们站在B的⻆度来观察来定义事务的传播⾏为
    PROPAGATION_REQUIRED :如果当前没有事务,就新建⼀个事务,如果已经存在⼀个事务中,加⼊到这个事务中。这是最常⻅的选择。
    PROPAGATION_SUPPORTS: ⽀持当前事务,如果当前没有事务,就以⾮事务⽅式执⾏。
    ps:这两种用得比较多
上一篇下一篇

猜你喜欢

热点阅读