Spring相关知识

47 阅读3分钟

image.png

spring框架有多个模块,核心容器的模块是核心,包括配置模型和依赖项注入机制,并且qpring框架给不同的体系结构提供了基础支持,比如我们的消息传递,事务性数据和持久性、web等 。他包括一个基于servlet的springMVC web框架,和并行的(不是基于servlet)的Spring WebFlux反应式

spring框架里面的bean,默认是singleton,表示每一个IOC容器里面只有一个实例(提供@Scope注解配置)。但是他不是线程安全的!!!

为啥不是安全的捏? 比如这个代码

image.png

这里我们的count需要考虑线程安全,但是多个线程操作时候,没有线程安全了。那么成员变量呢?Spring Bean里面一般注入的都是没有可变状态(无状态)的比如Service类和Dao类,如果在bean里面定义了可修改成员变量,需要考虑线程安全问题,可用使用多例或者加锁完成。

AOP:面向切面编程,就是把和业务无关的,但是对多个对象产生影响的公共行为逻辑,抽取处理,封装成一个可重用模块,以此来减少重复代码,降低模块耦合度,提供系统的可维护性。spring管理的事务,底层就是aop,aop又是使用的动态代理。

常用场景:日志、缓存、内置事务处理。

日志:aop的环绕通知+切点表达式

事务:编程式和声明式事务

  • 编程式事务:需要TransationTemplate来进行实现,对业务代码有侵入性,项目里面很少使用

  • 声明式事务:建立在AOP之上,本质就是通过AOP功能,对方法前后进行拦截,把事务处理的功能编织到拦截的方法里面,也就是在目标方法开始之前,加入一个事务,执行完成后按照执行情况选择提交事务或者回滚事务。

事务失效场景:

  1. 异常处理(抛出检查异常导致事务不能正确回滚) 因为:String默认只会回滚非检查异常(事务通知只有拿到了目标抛出的异常,才能进行后续的回顾处理,如果目标自己处理掉了异常,通知就无法拿到捏)。解决:在catch里面添加一个throw new RuntimeExpetion(e)抛出

  2. 抛出检查异常: 因为:spring默认只会回滚非检查异常。解决:@Transactional(rollbackFor=Exception.class)

  3. 非public方法导致的事务失效 原因:Spring为方法创建代理、添加事务通知的嵌套条件都是该方法是public。

Spring的Bean生命周期

spring容器在进行实例化的时候,会把xml配置的信息封装错误一个BeanDefinition对象,Spring按照BeanDefinition来创建bean对象,里面有很多的书写来描述bean。

构造函数-》依赖注入-》Aware接口-》BeanPostProcessor#before-》初始化方法-》BeanPostProcessor#after-》销毁bean