首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Spring整体架构知识构建

一、Spring两大核心

1、IOC

IOC其实它是一种思想,“控制反转”(官方解释),其实这种思想就是 将原本在我们自己写的程序里面去创建对象的权利,交给Spring框架来管理。

IOC容器是Spring 用来实现Ioc的载体,Ioc容器实际上就是Map的结构,里面存放的是各种对象

IOC容器就像一个工厂一样,当我们需要创建一个对象的时候,只需要配置好配置文件 / 注解,完全不用考虑对象是怎么配置出来的。(典型的工厂模式)

2、AOP

AOP:面向切面编程(说实话,直接这么说是一脸懵逼的),就是将那些与业务无关的,但是又是这个业务模块所共同调用的逻辑对吧,我们就把他们抽取出来,自己封装起来,统一调用。这样极大程度的减少了重复代码的书写,并且降低了系统的耦合度,利于扩展和维护。(典型的应用就是一些日志管理呀,比如说我想要将调用的每一个controller知道他的调用时间,并且入库,对吧,这时候我们写个切面是很好的处理)

核心是动态代理,若果代理的对象实现了某个接口,那么spring AOP就会使用JDK动态代理,去创建对象。对于没有实现接口的对象,spring aop会使用Cglib动态代理生成一个被代理的子类作为代理对象

AspectJ AOP:编译时增强,当切面太多的话,最好选择 AspectJ ,它比Spring AOP 快很多。

AOP切面是一个实现举例

二、Spring bean

1、Bean的作用域

singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。

prototype : 每次请求都会创建一个新的 bean 实例。

request : 每一次HTTP请求都会产生一个新的bean,该bean仅在当前HTTP request内有效。

session : 每一次HTTP请求都会产生一个新的 bean,该bean仅在当前 HTTP session 内有效。

2、线程安全问题

多个线程操作同一个对象的时候,对这个对象的成员变量的写操作会存在线程安全问题。

一般情况下,我们常用的 、、 这些 Bean 是无状态的。无状态的 Bean 不能保存数据,因此是线程安全的。

解决办法:

在类中定义一个  成员变量,将需要的可变成员变量保存在  中(推荐的一种方式)。

改变 Bean 的作用域为 “prototype”:每次请求都会创建一个新的 bean 实例,自然不会存在线程安全问题。

3、Bean的生命周期

Bean 容器(IOC容器)首先找到配置文件的中的Spring Bean的定义

Bean 容器利用反射来创建Bean的一个实例

如果涉及到一些属性,那么就利用方法来设置一些属性值

如果 Bean 实现了  接口,调用 方法,传入Bean的名字。

如果 Bean 实现了  接口,调用 方法,传入 对象的实例。

如果实现了其他 接口,就调用相应的方法。

如果有和加载这个 Bean 的 Spring 容器相关的  对象,执行 方法

如果Bean实现了接口,执行方法。

如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。

如果有和加载这个 Bean的 Spring 容器相关的  对象,执行 方法

当要销毁 Bean 的时候,如果 Bean 实现了  接口,执行  方法。

当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。

4、循环依赖问题

循环依赖其实就是循环引用,也就是两个或则两个以上的bean互相持有对方,最终形成闭环。比如A依赖于B,B依赖于C,C又依赖于A。

如果是我们自己写的,就会无限创建对象,(类似于死循环),导致内存占满报错,那么Spring是如何解决这种情况呢?

Java中的循环依赖分两种,一种是构造器的循环依赖,另一种是属性的循环依赖。

Spring解决的循环依赖就是指属性的循环依赖

首先我们先介绍一下Spring的三级缓存:

singletonObjects 一级缓存,用于保存实例化、注入、初始化完成的bean实例

earlySingletonObjects 二级缓存,用于保存实例化完成的bean实例

singletonFactories 三级缓存,用于保存bean创建工厂,以便于后面扩展有机会创建代理对象。

ps:盗用一张图(发生了什么??):

三、Spring 中的事务问题

其实,在我的理解里面Spring的事务是跟数据库保持一致的,如果我们选择的数据库它不支持事务(比如myisam),那么我们Spring里面的事务就不会起到作用。

1、四种事务特征(ACID)

原子性:强调事务的不可分割

一致性:事务的执行前后,数据的完整性保持一致

隔离性:一个事务执行过程中,不受其他事务的干扰

持久性:事务一旦执行结束,数据就持久到数据库,不会因为数据库宕机而发生数据修改失败等

2、五种隔离级别(比数据库多了一个默认级别)

:使用数据库默认的事务隔离级别

:最低的隔离级别,使用这个隔离级别很少,因为它允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读

: 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生

: 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

: 最高的隔离级别,完全服从 ACID 的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

3、七种传播行为

支持当前事务

:默认的事务传播行为,如果当前存在事务,则加入该事务,如果当时没有事务,则创建一个新事物。

:如果当前事务存在就加入该事务,如果不存在,则以非事务的方式运行

:如果当前事务存在就加入,不存在就抛出异常

不支持当前事务

:创建一个新的事务,如果存在当前的事务就挂起这个事务

:以非事务的方式运行,如果存在当前事务就挂起

:以非事务的方式运行,如果存在当前事务就抛出异常

其他

:嵌套事务,如果当前存在事务则在嵌套事务中执行,如果没有就以方式运行

------------END-----------

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20210318A04TW400?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券