也来聊聊Spring中的IOC和AOP

网友投稿 590 2022-05-30

作为一名Java开发的程序猿,spring可以说是每天都要打交道的东西,从最一开始基于xml配置文件的Spring再到Spring Boot或是Spring Cloud,可以明显感觉到的就是业务的搭建变得日益简单,配置由复杂变得越来越轻量,甚至只需要在网页上点一点就能初始化一个可以运行的Spring项目。网上讨论Spring核心概念IOC和AOP的文章也有很多,今天我也想来聊聊在我看来Spring IOC和AOP的一些特点和使用时需要注意的地方。

IOC

IOC是构成Spring常用模块中最核心的模块BeanFactory使用到的最重要的技术,通过控制反转,应用程序的配置和依赖规范可以很好的与应用程序代码分离开。我们不再需要从一个类引用另一个类时显式地初始化对方,而是可以单纯的通过某个配置文件就能描述组成Spring应用的各个类之间的依赖关系。通过Java语言的反射功能就可以实例化各个Bean并建立他们之间的依赖关系。IOC除了这些功能以外,还提供了Bean实例缓存、生命周期管理、Bean实例代理发布、事件发布、资源装载等等高级功能。

说起IOC,最重要的就是BeanFactory,这是面向Spring框架基础本身的一个类,而我们的开发者更多的使用ApplicationContext。

Bean的类型有两种,一种是单例Singleton,一种是prototype,分别会在使用的过程中共享同一个Bean或者每次分别创建不同的Bean。在Web场景下Bean还有request、session和global session三种额外的作用域。

Spring Bean的生命周期大概是:

实例化

IOC依赖注入

setBeanName

BeanFactoryAware

ApplicationContextAware

postProcessBeforeInitialization

init-method

postProcessAfterInitialization

Destory过期自动清理

Destory-method

依赖注入的四种方式:

构造器注入

setter注入

静态工厂注入

实例工厂注入

AOP

核心概念:

切面:对横切关注点的抽象

横切关注点:对哪些方法进行拦截,拦截后进行什么样的处理

连接点:被拦截到的点

切入点:对拦截点进行拦截的定义

增强:进行拦截之后要进行的处理,分别有-前置,后置,异常,返回值,环绕

目标对象:要进行代理的目标

织入:将切面应用于目标对象并创建代理对象的过程

也来聊聊Spring中的IOC和AOP

引入:不改变代码的前提下运行期修改类,动态添加方法或者字段

两种代理方式:

JDK动态接口代理:

要求横切逻辑必须是接口定义的,通过反射调用目标类的代码,动态的将横切逻辑和业务逻辑进行编织

CGLib动态代理:

高性能的代码生成类库,不受被代理对象是否实现了接口的限制,可以默认关闭JDK动态代理而完全使用CBLib动态代理

循环依赖问题

Spring 为了解决单例的循环依赖问题,使用了 三级缓存 ,递归调用时发现 Bean 还在创建中即为循环依赖

单例模式的 Bean 保存在如下的数据结构中:

/** 一级缓存:用于存放完全初始化好的 bean **/ private final Map singletonObjects = new ConcurrentHashMap(256); /** 二级缓存:存放原始的 bean 对象(尚未填充属性),用于解决循环依赖 */ private final Map earlySingletonObjects = new HashMap(16); /** 三级级缓存:存放 bean 工厂对象,用于解决循环依赖 */ private final Map> singletonFactories = new HashMap>(16); /** bean 的获取过程:先从一级获取,失败再从二级、三级里面获取 创建中状态:是指对象已经 new 出来了但是所有的属性均为 null 等待被 init */

1

2

3

4

5

6

7

8

9

10

11

12

13

14

检测循环依赖的过程如下:

A 创建过程中需要 B,于是 A 将自己放到三级缓里面 ,去实例化 B

B 实例化的时候发现需要 A,于是 B 先查一级缓存,没有,再查二级缓存,还是没有,再查三级缓存,找到了!

然后把三级缓存里面的这个 A 放到二级缓存里面,并删除三级缓存里面的 A

B 顺利初始化完毕,将自己放到一级缓存里面(此时B里面的A依然是创建中状态)

然后回来接着创建 A,此时 B 已经创建结束,直接从一级缓存里面拿到 B ,然后完成创建,并将自己放到一级缓存里面

如此一来便解决了循环依赖的问题

AOP Java Spring

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:数字中国创新大赛决赛名单出炉,与华为云 EI 一起挑战书法识别
下一篇:云计算的技术特点
相关文章