Spring高级特性:
1.lazy-init:配置bean对象的延迟加载,true或者false,默认为fasle(立即加载),相当于注解@Lazy
如果⼀个 bean 的 scope 属性为 scope="pototype" 时,即使设置了 lazy-init="false",容器启动时也不会实例化bean,⽽是调⽤ getBean ⽅法实例化的。
应⽤场景
(1)开启延迟加载⼀定程度提⾼容器启动和运转性能
(2)对于不常使⽤的 Bean 设置延迟加载,这样偶尔使⽤的时候再加载,不必要从⼀开始该 Bean 就占⽤资源
2.FactoryBean 和 BeanFactory
BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的⼀个⼯⼚,具体使⽤它下⾯的⼦接⼝类型,⽐如ApplicationContext;
此处我们重点分析FactoryBean,Spring中Bean有两种,⼀种是普通Bean,⼀种是⼯⼚Bean(FactoryBean),FactoryBean可以⽣成某⼀个类型的Bean实例(返回给我们),也就是说我们可以借助于它⾃定义Bean的创建过程。
Bean创建的三种⽅式中的静态⽅法和实例化⽅法和FactoryBean作⽤类似,FactoryBean使⽤较多,尤其在Spring框架⼀些组件中会使⽤,还有其他框架和Spring框架整合时使⽤。
Spring源码深度剖析
1.IOC源码深度剖析
好处:提高培养代码框架思维、深入理解框架
原则
定焦原则:抓主线
宏观原则:站在上帝的视角,关注源码结构和业务流程(淡化具体某行代码的编写细节)
读源码的方法和技巧
断点(观察调用栈)
反调(Find Usages)
经验(Spring框架中doXXX,做具体处理的地方)
Spring源码构建
下载源码(github)
安装gradle(5.6.3)类似于maven
导入(需要耗费一定时间)
Spring AOP应用
AOP本质:在不改变原有业务逻辑的情况下增强横切逻辑,横切逻辑代码往往是权限校验代码、⽇志代码、事务控制代码、性能监控代码
AOP术语:
连接点:方法开始时,结束时,执行完毕时,方法异常时等这些特殊的时机点,我们称之为连接点,连接点是一种候选点
切入点:指定AOP思想想要影响的具体方法是哪些
增强(通知):第一个层次:指的是横切逻辑;第二个层次:方位点(加入横切逻辑的连接点)
目的就是为了锁定要在哪个地方插入什么横切逻辑代码
Aspect切面:切面概念是对上述概念的一个综合,切面=切入点+增强=切入点+横切逻辑+方位点
=切入点(锁定方法)+方位点(锁定方法中的特殊时机)+横切逻辑
Spring 实现AOP思想使⽤的是动态代理技术
默认情况下,Spring会根据被代理对象是否实现接⼝来选择使⽤JDK还是CGLIB。当被代理对象没有实现
任何接⼝时,Spring会选择CGLIB。当被代理对象实现了接⼝,Spring会选择JDK官⽅的代理技术,不过
我们可以通过配置的⽅式,让Spring强制使⽤CGLIB。
在Spring的AOP配置中,也和IoC配置⼀样,⽀持3类配置⽅式。
第⼀类:使⽤XML配置
<!--横切逻辑bean-->
<bean id = "logUtils" class="com.lagou.edu.utils.LogUtils"></bean>
<!--切面aspect = 切入点(锁定方法)+方位点(锁定方法中的特殊时机)+横切逻辑-->
<aop:config>
<aop:aspect id = "logAspect" ref="logUtils">
<!--切入点锁定我们感兴趣的方法,使用aspectj语法表达式-->
<aop:pointcut id="ptl" expression="execution(public void com.lagou.edu.service.impl.TransferServiceImpl.transfer(java.lang.String,
java.lang.String,int))"/>
<!--方位信息-->
<aop:before method="beforeMethod" pointcut-ref="ptl"/>
</aop:aspect>
</aop:config>
第⼆类:使⽤XML+注解组合配置
第三类:使⽤纯注解配置
Spring声明式事务的支持
编程式事务:在业务代码中添加事务控制代码,这样的事务控制机制就叫做编程式事务
声明式事务:通过xml或者注解配置的⽅式达到事务控制的⽬的,叫做声明式事务
事务的四大特性:
原子性:从操作的角度来描述,事务中的各个操作要么都成功要么都失败
一致性:从数据的角度来说的,
隔离性:解决脏读,隔离级别
持久性:一旦提交,数据库发生故障,也不会对其产生影响
事务的隔离级别:为隔离级别在解决事务并发问题
脏读:一个事务读取了另外一个事务未提交的数据;
不可重复读:一个线程中的事务读取了另外一个线程中已经提交的update的数据(前后内容不一样)
场景:
员⼯A发起事务1,查询⼯资,⼯资为1w,此时事务1尚未关闭
财务⼈员发起了事务2,给员⼯A张了2000块钱,并且提交了事务
员⼯A通过事务1再次发起查询请求,发现⼯资为1.2w,原来读出来1w读不到了,叫做不可重复读
幻读:一个线程中的事务读取了另外一个线程中已经提交的insert的数据(前后内容不一样)
场景:
事务1查询所有⼯资为1w的员⼯的总数,查询出来了10个⼈,此时事务尚未关闭
事务2财务⼈员发起,新来员⼯,⼯资1w,向表中插⼊了2条数据,并且提交了事务
事务1再次查询⼯资为1w的员⼯个数,发现有12个⼈,⻅了⻤了
数据库定义了四种隔离级别:
Serializable(串行化):可避免脏读、不可重复读、幻读情况的发生 最高
Repeatable read(可重复度):可避免脏读、不可重复读、,幻读有可能发生 第二
该机制下会对update的行进行加锁。对于insert没有加锁,幻读是insert
Read committed(读已提交):可避免脏读情况发生,不可重复度和幻读一定会发生 第三
Read umcommitted(读未提交):最低级别,以上情况均无法保证 最低
MYSQL的默认隔离级别是:Repeatable read(可重复度)
查询当前使⽤的隔离级别: select @@tx_isolation;
设置MySQL事务的隔离级别: set session transaction isolation level xxx; (设置的是当前
mysql连接会话的,并不是永久改变的
spring声明式事务配置,声明式事务无非就是配置一个aop,只不过有些标签不一样罢了