IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 对Spring IOC控制反转的详细理解 -> 正文阅读

[Java知识库]对Spring IOC控制反转的详细理解

IOC是什么

????Spring的IOC意思为控制反转,它不是什么技术,而是一种设计思想。它是将你设计好的对象交给Spring容器来控制,而不是由我来管理对象,给它赋值等等。

问题一:谁控制谁?控制什么

????传统的面向对象思想对于构造对象最简单的方法无非就是在对象内部通过new对对象进行创建,是程序主动去创建依赖对象。
????但IOC不同,IOC是专门有一个容器来创建、初始化这些对象,这些对象被称为Bean。谁控制谁? 是IOC容器控制住了对象控制了什么? 控制了bean的生命周期。

问题二:为何是反转,哪方面反转了

????有反转就有正转,面向对象思想就是有我们在自己的对象中主动控制去直接获取依赖对象,这就是正转。而反转就是由Spring容器来创建及注入依赖对象。为何是反转? 因为有容器来自动的帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转。哪方面反转了? 依赖对象的获取被反转了。

DI依赖注入

????IOC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。在生产bean的过程中,需要解决bean之间的依赖问题,才引入了依赖注入(DI)这种技术。也就是说依赖注入是beanFactory生产bean时为了解决bean之间的依赖的一种技术而已。

对象如何生成(BeanFactory和ApplicationContext的区别)

????刚说的IOC就是由Spring来接手对象的创建、生命周期和对象间的关系。

????Spring的本质就是一个bean工厂或者说bean容器,它按照我们的需求创作出各种各样的bean。
????beanFactory会在bean的生命周期的各个阶段中对bean进行各种管理,并且spring将这些阶段通过各种接口暴露给我们,让我们可以对bean进行各种处理,我们只要让bean实现对应的接口,那么spring就会在bean的生命周期调用我们实现的接口来处理该bean。

BeanFactory和ApplicationContext

????在 spring 容器中,BeanFactory 接口是 IOC 容器要实现的最基础的接口,定义 了管理 bean 的最基本的方法。主要是面向spring框架本身,不支持AOP和web功能. 在获取bean时才会创建beanApplicationContext 继承BeanFactory接口,对功能进行扩展. 支持aop,web等插件,面向开发层面, 可以在框架启动时,就可以创建bean。如果说BeanFactory是心脏,那么ApplicationContext就是躯体。
在这里插入图片描述

Bean的生命周期

在这里插入图片描述

IOC控制了Bean的生命周期,就是Spring管理Bean的过程,

  1. 实例化,等同于new
  2. 属性赋值、注入
  3. 初始化,根据各种配置进行对象初始化。例如类具有事务管理功能,再次阶段生成代理对象。
    1. 若Bean实现了BeanNameAware接口,调用setBeanName(),将bean的id传给setBeanName
    2. 若Bean实现了BeanFactoryAware接口,调用setApplicationContext() 进行初始化
    3. 若Bean实现了ApplicationContextAware接口,调用setApplicationContext() 进行初始化
    4. 若Bean实现了BeanPostProcessor接口(AOP),调用postProcessBeforeInitialization() 进行初始化
    5. 若Bean实现了InitializingBean接口 或 bean使用<bean init-method="初始化方法">声明了初始化方法,调用afterPropertiesSet()进行初始化
    6. 若Bean实现了BeanPostProcessor接口(AOP),调用postProcessAfterInitialization() 进行初始化
  4. Bean的使用然后销毁阶段

在这里插入图片描述

Bean的线程安全

Spring中的Bean不是线程安全的

????线程安全问题,还需要从单例bean和原型bean说起
????线程安全问题是指在单咯bean的情况下,对象值创建了一个。如果拥有成员变量,它是共享的,所以线程不安全,可以使用ThreadLocal为每个线程申请一个变量副本,来解决线程安全问题。这种情况是单例Bean。在单例的设计模式中,对象只创建一次,多线程共享一个Bean对象,存在并发编程问题。而原型Bean是没有线程安全问题的,因为每个线程申请进来都会创建一个Bean对象,他们之间不存在成员变量共享问题。
在这里插入图片描述

Bean的循环依赖

什么是循环依赖?

????在JavaSE中,循环依赖是很正常的现象。比如A类的属性有B类的对象,B类的属性又有A类的对象。这就叫循环依赖。在使用的时候没有问题。
在这里插入图片描述
????但是在Spring中,对象的创建不是我们在操作,而是Spring容器,他会给对象注入值。对象的创建需要为其注入依赖对象的值才可以,A的创建需要注入B,但是B的创建有需要注入A,问题就来了,不解决的话会陷入死循环。归根结底 循坏依赖的本质问题就是Spring不允许为对象注入Null值

如何解决循环依赖?
在这里插入图片描述
三层缓存机制:

  1. 一级缓存 singletonObjects:保存实例化、属性注入、初始化完成的Bean
  2. 二级缓存 earlySingletonObjects:保存实例化完成的Bean(实例化完成,对象不为null,就可以注入,解决了循环依赖)
  3. 三级缓存 singletonFactories:保存Bean工厂,以便后期添加其他代理对象(如事务管理中代理对象的生成)

构造方法注入无法解决循环依赖问题
在构造方法中使用@Lazy标识依赖的属性参数,可以解决

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-06-14 22:21:09  更:2022-06-14 22:22:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 18:53:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码