Java——Spring的控制反转(一文详解IOC)

news2024/7/11 12:20:09

SpringSpring MVCSpring Boot 三者比较

答: 这三者专注的领域不同,解决的问题也不一样;总的来说,Spring 就像一个大家族,有众多衍生产品例如 BootSecurityJPA等等。但他们的基础都是 Spring IOC AOPIOC提供了依赖注入的容器,而AOP解决了面向切面的编程,然后在此两者的基础上实现了其他衍生产品的高级功能;Spring MVC是基于 Servlet 的一个 MVC 框架主要解决 WEB 开发的问题。与此同时, Spring 的配置非常复杂,各种xmlproperties处理起来比较繁琐。于是为了简化开发者的使用Spring社区创造性地推出了Spring Boot,它遵循约定优于配置,极大降低了Spring使用门槛,但又不失Spring原本灵活强大的功能,下面用一张图来描述三者的关系:

在这里插入图片描述

最后一句话总结:Spring MVC Spring Boot 都属于 Spring Spring MVC 是基于 Spring 的一个 MVC 框架,而 Spring Boot 是基于 Spring 的一套快速开发整合包

1、什么是Spring IOC容器?

答:控制反转即IOC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。

Spring IOC负责创建对象,管理对象(通过依赖注入(DI),配置对象,装配对象,并且管理这些对象的整个生命周期)。

2、控制反转(IOC)有什么作用?

  • 管理对象的创建和依赖关系的维护: 对象的创建并不是一件简单的事,在对象关系比较复杂时,如果依赖关系需要程序猿来维护的话,那是相当头疼的。
  • 解耦: 由容器去维护具体的对象。
  • 托管了类的产生过程: 比如我们需要在类的产生过程中做一些处理,最直接的例子就是代理,如果有容器程序可以把这部分处理交给容器,应用程序则无需去关心类是如何完成代理的。

3、IOC的优点是什么?

  • IOC 或 依赖注入把应用的代码量降到最低
  • 它使应用容易测试,单元测试不再需要单例和JNDI查找机制。
  • 最小的代价和最小的侵入性使松散耦合得以实现。
  • IOC容器支持加载服务时的饿汉式初始化和懒加载

4、Spring IOC 的实现原理?

答: 工厂模式加反射机制。

interface Fruit {
   public abstract void eat();
}

class Apple implements Fruit {
    public void eat(){
        System.out.println("Apple");
    }
}

class Orange implements Fruit {
    public void eat(){
        System.out.println("Orange");
    }
}

class Factory {
    public static Fruit getInstance(String ClassName) {
        Fruit f = null;
        try {
            f = (Fruit)Class.forName(ClassName).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }
}

class Client {
    public static void main(String[] a) {
        Fruit f=Factory.getInstance("spring.Apple");
        if(f!=null){
          f.eat();
        }
    }
}

5、BeanFactoryApplicationContext有什么区别?

答: BeanFactoryApplicationContext 是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContextBeanFactory子接口

5.1、依赖关系

  • BeanFactory Spring里面最底层的接口,包含了各种Bean的定义,读取Bean配置文档,管理 Bean 的加载、实例化,维护 Bean 之间的依赖关系和控制 Bean 的生命周期,
  • ApplicationContext 该接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:
    • 继承MessageSource,因此支持国际化。
    • 统一的资源文件访问方式。
    • 提供在监听器中注册Bean的事件。
    • 同时加载多个配置文件
    • 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。

5.2、加载方式

答:ApplicationContext相对于基本的BeanFactoryApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。

  • BeanFactroy BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化。这样,我们就不能发现一些存在的Spring的配置题。如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用 getBean() 方法才会抛出异常
  • ApplicationContext ApplicationContext是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入ApplicationContext启动后预载入所有的单实例Bean,通过预载入单实例Bean,确保当你需要的时候,你就不用等待,因为它们已经创建好了。

5.3、创建方式

答: BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader

5.4、注册方式

答: BeanFactoryApplicationContext都支持 BeanPostProcessorBeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory 需要手动注册,而 ApplicationContext 则是自动注册

6、Spring 如何设计容器的,BeanFactoryApplicationContext的关系详解?Spring控制反转(IOC)

Spring作者 Rod Johnson 设计了两个接口用以表示容器。

  • BeanFactory
  • ApplicationContext
  1. BeanFactory简单粗暴,可以理解为就是个HashMapKey BeanName Value Bean 实例。通常只提供注册(put),获取(get)这两个功能。我们可以称之为 “低级容器
  2. ApplicationContext 可以称之为 “高级容器”。因为他比BeanFactory多了更多的功能。他继承了多个接口。因此具备了更多的功能。例如资源的获取,支持多种消息(例如JSP tag的支持),对BeanFactory 多了工具级别的支持等待。所以你看他的名字,已经不是BeanFactory之类的工厂了,而是 “应用上下文”, 代表着整个大容器的所有功能。该接口定义了一个 refresh ()方法,此方法是所有阅读 Spring 源码的人的最熟悉的方法,用于刷新整个容器,即重新加载/刷新所有的 Bean
  3. 为了更直观的展示 “低级容器” 和 “高级容器” 的关系,这里通过常用的ClassPathXmlApplicationContext 类来展示整个容器的层级 UML 关系。

7、ApplicationContext通常的实现是什么?

  • FileSystemXmlApplicationContext 此容器从一个XML文件中加载Beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。
  • ClassPathXmlApplicationContext 此容器也从一个XML文件中加载Beans的定义,这里,你需要 正确设置 classpath 因为这个容器将在classpath里找Bean配置。
  • WebXmlApplicationContext 此容器加载一个XML文件,此文件定义了一个WEB应用的所有Bean

8、什么是Spring的依赖注入?

答: 控制反转IOC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:依赖注入和依赖查找。面向接口编程中,让依赖注入只需要找到符合规范的接口注入即可实现调用者和被调用者解耦。对象的调用关系由Spring管理。

  • 依赖注入: 是指程序运行过程中,如果需要创建一个对象,无须再代码中new创建,而是依赖外部的注入Spring的依赖注入对调用者和被调用者几乎没有任何要求,完全支持对pojo之间依赖关系的管理;
  • new 对象: 类的头部进行实例化对象和依赖注入一个效果,这个时候该对象不管是否使用都贯穿该类的始终。该类对象不被回收,这个实例化对象也不会被回收。如果要使用多例对象则最好使用new创建对象而不是依赖注入,即使依赖注入有多例模式也不推荐。

9、依赖注入有什么优势?

答: 依赖注入之所以更流行是因为它是一种更可取的方式:让容器全权负责依赖查询,受管组件只需要暴露JavaBeanSetter方法或者带参数的构造器或者接口,使容器可以在初始化时组装对象的依赖关系。其与依赖查找方式相比,主要优势为:

  • 查找定位操作与应用代码完全无关。
  • 不依赖于容器的API,可以很容易地在任何容器以外使用应用对象。
  • 不需要特殊的接口,绝大多数对象可以做到完全不必依赖容器。

10、有哪些不同类型的依赖注入实现方式?

答: 依赖注入是时下最流行的IOC实现方式,依赖注入分为接口注入(Interface Injection)Setter方法注入(Setter Injection)和构造器注入(Constructor Injection)三种方式。其中接口注入由于在灵活性和易用性比较差,现在从Spring4开始已被废弃。

  • 构造器依赖注入: 构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。
  • Setter 方法注入: Setter方法注入是容器通过调用无参构造器或无参 static 工厂方法实例化Bean之后,调用该Beansetter方法,即实现了基于setter的依赖注入。

构造器依赖注入和 Setter方法注入的区别

构造函数注入setter注入
没有部分注入有部分注入
不会覆盖setter属性会覆盖setter属性
任意修改都会创建一个新实例任意修改不会创建一个新实例
适用于设置很多属性适用于设置少量属性

两种依赖方式都可以使用,构造器注入和Setter方法注入。最好的解决方案是用构造器参数实现强制依赖, setter 方法实现可选依赖

11、Spring的循环依赖怎么理解?

答: 循环依赖是指在创建 Bean 的时候,两个为创建未完成的Bean 互相引用,形成循环。循环依赖分为三种:

  • 构造器的循环依赖: 这种依赖Spring是处理不了的,直接抛出BeanCurrentlylnCreationException异常。
  • 单例模式下的 setter 循环依赖: 通过 “三级缓存” 处理循环依赖。
    • singletonObjects:一级缓存,用于保存实例化、注入、初始化完成的Bean实例;
    • earlySingletonObjects: 二级缓存,用于保存实例化完成的Bean实例;
    • singletonFactories:三级缓存,用于保存Bean创建工厂,以便于后面扩展有机会创建代理对象。
  • 非单例循环依赖: 无法处理。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1136024.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Sectigo代码签名证书

自数字化时代以来,软件开发领域一直在迅速发展,而数字签名成为了确保软件和应用程序的完整性和可信性的关键元素之一。Sectigo代码签名证书作为数字签名的一个重要组成部分,为开发者和软件供应商提供了一种可靠的方式来证明其代码的来源和完整…

charles抓包手机的http

一,先写抓包手机的http 1,设置charles 按照如图设置charles,之后拿到ip地址. 2,手机端配置网络 手机连上和电脑同一个局域网,在无线按钮长按或者右键,手动配置ip,配置成刚刚第一步取到的ip和端口: 在配置好之后,电脑会弹出一个弹窗: 点击allow,就能狗抓取手机http的包了.

SAAS智能打印设计->自定义打印模板

1 业务场景 企业在业务运转过程中经常需要在线打印凭证、采购单、出入库单据等等。这时,你可以使用SAAS版打印设计器,根据自身需求自行设计打印模板,无论是打印纸张规格、打印方向,还是打印样式,你都可以自由调整设计…

目前和未来的缓存构建

说起来可能有点反直觉,有时候不运行反而可以帮助我们加快速度,这正是网络浏览器运行的指导原则。不必在页面上加载所有内容,缓存的元素已经存在,不需要每次访问网站或网页时都重新加载。页面加载速度越快,浏览器的工作…

windows 离线安装 vue 环境

由于公司要求在内网开发项目,而内网不能连接外网,因此只能离线安装 vue 环境,在网上找过很多的离线安装方法,但都没有成功,于是在不断的尝试中找到了以下方法。 1、找一台与内网电脑相同系统的有网电脑。 2、在有网的电…

Power BI 实现日历图,在一张图中展示天、周、月数据变化规律

《数据可视化》这本书里介绍了一个时间可视化的案例(如下图所示),以日历图的形式展示数据的变化,可以在一张图上同时观察到:(1)每一天的数据变化;(2)随周变化…

1024 云上见 · 上云挑战(ChatGPT搭建)

【玩转1024】使用函数计算X通义千问搭建AI助手,参与1024小说创作大赛 【使用函数计算X通义千问搭建AI助手,参与小说创作大赛】:本活动基于函数计算X 通义千问快速部署 AI 个人助手应用,用户可以根据需要选择不同角色的AI助手开启…

Python开发利器KeymouseGo,开源的就是香

1、介绍 在日常工作中,经常会遇到一些重复性的工作,不管是点击某个按钮、写文字,打印,还是复制粘贴拷贝资料之类的,需要进行大量的重复操作。按键精灵大家想必都听说过,传统的方式,可以下载个按…

山东大学开发可解释深度学习算法 RetroExplainer,4 步识别有机物的逆合成路线

逆合成旨在找到一系列合适的反应物,以高效合成目标产物。这是解决有机合成路线的重要方法,也是有机合成路线设计的最简单、最基本的方法。 早期的逆合成研究多依赖编程,随后这一工作被 AI 接替。然而,现有的逆合成方法多关注单步逆…

基于STM32温室智能监测控制系统设计

**单片机设计介绍,基于STM32温室智能监测控制系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序程序文档 六、 文章目录 一 概要 设计功能包含温湿度检测、光照强度检测,可以通过温湿度和光照来控制灯和电机风扇运转。包含的…

Java多线程秘籍,掌握这5种方法,让你的代码优化升级

介绍5种多线程方法,助您提高编码效率! 如果您的应用程序与那些能够同时处理多个任务的应用程序相比表现不佳,很可能是因为它是单线程的。解决这个问题的方法之一是采用多线程技术。 以下是一些可以考虑的方法: 线程(…

Mac第三方恶意软件删除不了怎么办,这个方法你尝试了吗?

大多使用Mac电脑的用户,难免会遇到强制弹广告窗或者有些恶意软件在Mac电脑里删不掉的情况。是的,你的Mac可能已经感染了恶意软件。恶意软件除了传统的病毒、蠕虫和特洛伊木马之外,还有一个蓬勃发展的广告软件和间谍软件程序生态系统&#xff…

AT32固件库外设使用,ArduinoAPI接口移植,模块化

目录 一、ArduinoAPI移植一、通用定时器使用1.计时1.2.ETR外部时钟计数4.ArduinoAPI - timer 三、ADC1.ADC初始化(非DMA)2.ADC_DMA 规则通道扫描 六、USB HID IAP1.准备好Bootloader和app2.配置好时钟,一定要打开USB3.将生成的时钟配置复制到…

每日汇评:黄金形态确认牛市,再次尝试上行2000美元

金价挑战1988美元的关键阻力位,向2000美元进发; 在避险情绪中,美元随着美债收益率扩大复苏; 黄金价格在日线图上确认了一个多头标志,RSI指数仍然指向更多的上涨; 随着中东紧张局势再次引起人们的关注&#…

前列腺特异抗原(PSA)介绍

前列腺特异抗原(Prostate Specific Antigen,PSA)是由前列腺腺泡和导管的上皮细胞分泌的一种单链糖蛋白,在功能上属于类激肽释放酶的一种丝氨酸蛋白酶,参与精液的液化过程,是常规用于前列腺良性与恶性疾病诊断与鉴别诊断的重要指标…

LuaTable转C#的列表List和字典Dictionary

LuaTable转C#的列表List和字典Dictionaty 介绍lua中创建表测试lua中list表表转成List表转成Dictionary 键值对表表转成Dictionary 多类型键值对表表转成Dictionary 总结 介绍 之前基本都是从C#中的List或者Dictionary转成luaTable,很少会把LuaTable转成C#的List或者…

openEuler 22.03 LTS编译安装libreoffice并制作rpm包——筑梦之路

环境说明 操作系统:华为欧拉操作系统openEuler 22.03 lts x86_64 libreoffice版本:当前最新版本7.6 编译安装过程 1. 安装编译工具和依赖包 sudo yum install -y snappy snappy-devel autoconf automake libtool git gcc gcc-c gcc-objc make cmake…

超全整理,服务端性能测试-docker部署tomcat/redis(详细步骤)

目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、docker部署tom…

全电注塑机硬件选型

电机选型(方法) 在伺服电机选型计算当中其主要数据包括:负载/ 电机惯量比,加减速力矩, 负载转矩,连续过载时间等。选择原则是:首先根据转矩-速度特性曲线检查负载转矩,加…