Spring IoCDI (1)

2024-05-05 20:52
文章标签 java spring iocdi

本文主要是介绍Spring IoCDI (1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、IoC & DI入门

1、Spring是什么

(1)什么是容器?

(2)什么是IoC?

二、IoC介绍

1、传统程序开发

2、解决方案

3、IoC程序开发

4、IoC优势

三、DI介绍


        通过前面的学习,我们知道Spring是一个开源框架,它能让我们的开发更简单,它支持广泛的应用场景,有着活跃而庞大的社区,这也是Spring长久不衰的原因。但是这个概念还是比较抽象的,我们用一句更具体的话来概括Spring:Spring是包含了众多工具方法的IoC容器

一、IoC & DI入门

1、Spring是什么

(1)什么是容器?

        容器是用来容纳某种物品的(基本)装置。——来自:百度百科。生活中的水杯、垃圾桶、冰箱等等这些都是容器,之前接触过的容器:List/Map->数据存储容器、Tomcat->Web容器。

(2)什么是IoC?

        IoC是Spring的核心思想,也是常见的面试题,那么什么是IoC呢?其实IoC在前面的代码练习已经使用过了,比如在类上面添加 @RestController 和 @Controller 注解,就是把这个对象交给Spring管理,Spring框架启动时,就会加载该类。——把对象交给Spring管理,这就是IoC思想

        IoCInversion of Control(控制反转),也就是说Spring是一个“控制反转”的容器

什么是控制反转呢?就是控制权反转。什么控制权发生了反转?获得依赖对象的过程被反转了也就是说,当需要某个对象时,传统开发模式需要自己通过 new 创建对象,现在不需要再进行创建了,把创建对象的任务交给容器,程序中只需要依赖注入(Dependency Injection,简称DI)就可以了。这个容器称为:IoC容器。Spring是一个IoC容器,所以有时也称为Spring容器

        控制反转是一种思想,在生活中也处处体现比如自动驾驶,传统驾驶方式,车辆的横向和纵向驾驶控制权由驾驶员来控制,现在交给了驾驶自动化系统来控制,这也是控制反转思想在生活中的实现;还有招聘,企业的员工招聘、入职、解雇等控制权,由老板转交给HR(人力资源)来处理;还有外包等等


二、IoC介绍

下面通过案例来介绍什么是IoC,现在需求:造一辆车

1、传统程序开发

        我们是实现思路是这样的:先设计轮子(Tire),然后根据轮子的大小设计底盘(;),接着根据底盘设计车身(FrameWork),最后根据车身设计好整个汽车(Car)。这里就出现了一个 “依赖” 关系:汽车依赖车身,车身依赖底盘,底盘依赖轮子。如图:

        代码实现如下:

public class Main {public static void main(String[] args) {Car car = new Car();car.run();}
}public class Car {private FrameWork frameWork;public Car() {frameWork = new FrameWork(17);System.out.println("frameWork init....");}public void run() {System.out.println("Car run...");}
}public class FrameWork {private Bottom bottom;public FrameWork(int size) {bottom = new Bottom(size);System.out.println("Bottom init...");}
}public class Bottom {private Tire tire;public Bottom(int size) {tire = new Tire(size);System.out.println("Tire init....");}
}public class Tire {private int size;public Tire(int size) {this.size = size;}
}

        程序跑起来,控制台结果如图:

        

        但是现在又有需求了,要修改轮胎的颜色,那就要多添加一个属性,那么传参的时候,Car类、FrameWork类、Bottom类、Tire类的构造函数都要多添加一个元素,传参也要多传一个颜色属性。那么这样的话,耦合就很高而这也只是简单的给轮胎添加一个属性,随着项目需求的增加,项目也会越来越复杂,现在的代码可维护性也很差,就不太合适了。所以,要进行改进

2、解决方案

        上面的程序中,我们是根据轮胎的尺寸设计底盘的,轮胎的尺寸已改,底盘的设计也就得改,而车身依赖底盘,就会导致一连串的问题,几乎整个设计都得改。

        现在尝试换一种思路,我们先设计汽车的大概样子,然后根据汽车的样子来设计车身,根据车身来设计底盘,最后根据底盘设计轮胎。这时候,依赖关系就反转过来了:轮胎依赖底盘,底盘依赖车身,车身依赖汽车

这就类似我们造一辆完整的汽车,如果所有的配件都是自己造,那么客户需求发生改变的时候,比如轮胎尺寸不再是原来的尺寸了,那我们就要自己手动来改了,但如果把轮胎外包出去,那么即使轮胎的尺寸发生改变,那么我们只需要向代理工厂下订单就行了,我们自身是不需要出力的

        如何实现呢?我们可以尝试不在每个类中创建下级类,如果自己创建下级类就会出现当下级类发生改变操作,自己也要跟着修改。此时我们只需要将原来有自己创建的下级类,改为注入的方式,因为我们不需要在当前类中创建下级类了,所以下级类即使发生变化(创建或减少参数),当前类本身也无需修改任何代码,这样就完成了程序的解耦

3、IoC程序开发

        基于以上思路,我们把调用汽车的程序示例改造一下,把创建子类的方式,改为注入传递的方式。具体代码如下:

public class Main {public static void main(String[] args) {Tire tire = new Tire(17);Bottom bottom = new Bottom(tire);FrameWork frameWork = new FrameWork(bottom);Car car = new Car(frameWork);car.run();}
}public class Car {private FrameWork frameWork;public Car(FrameWork frameWork) {this.frameWork = frameWork;System.out.println("frameWork init....");}public void run() {System.out.println("Car run...");}
}public class FrameWork {private Bottom bottom;public FrameWork(Bottom bottom) {this.bottom = bottom;System.out.println("Bottom init...");}
}public class Bottom {private Tire tire;public Bottom(Tire tire) {this.tire = tire;System.out.println("Tire init....");}
}public class Tire {private int size;public Tire(int size) {this.size = size;System.out.println("size:" + size);}
}

        这样,如果轮胎需要修改尺寸,或者添加一个属性,只需要修改Tire类就好了,其他类不需要修改,达到了解耦的效果。

4、IoC优势

传统代码中的对象创建顺序是:Car -> Framework -> Bottom -> Tire

改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car

        我们发现了一个规律,通过程序的实现代码,类的创建顺序是反的,传统代码是Car控制并创建了Framework,Framework的创建也会继续创建Bottom,依次往下递推而改进后的控制权发生了反转,不再是使用方创建对象并控制依赖对象了,而是把依赖对象注入到当前对象中,依赖对象的控制权不再由当前类控制。这样的话,即使依赖类发生任何改变,当前类都是不受影响的,这就是典型的控制反转,也是IoC的实现思想。

        而控制反转容器也就是IoC容器,如图:

        这部分代码,也是IoC容器做的工作。

        从上面可以看出,IoC具有以下优点:资源不由使用资源的双方管理,而由使用资源的第三方管理,这可以带来很多好处。第一,资源集中管理,实现资源的可配置和易管理第二,降低使用资源双方的依赖程度,也就是我们说的耦合度

        资源集中管理IoC容器会帮我们管理一些资源(对象等),我们需要使用时,只需要从IoC容器中去取就可以了

        解耦合我们在创建实例的时候不需要了解其中的细节,降低了使用资源双方的依赖程度,也就是耦合度

        而Spring就是一种IoC容器,帮助我们来做了这些资源管理。


三、DI介绍

        DIDependency Injection(依赖注入)容器在运行期间,动态的为应用程序提供运行时所依赖的资源,称为依赖注入

        程序运行时,需要某个资源,此时容器就为其提供这个资源。从这点来看,依赖注入(DI)和 控制反转(IoC)是从不同的角度描述同一件事,就是指通过引入IoC容器,利用依赖关系注入的方式,实现对象之间的解耦

        上面改进后的代码,就是通过构造函数,把依赖对象注入到需要使用的对象中。如图:

        IoC是一种思想,也是 “目标”,而思想只是一种指导原则,最终还是要有可行的落地方案,而DI就属于具体的实现。所以也可以说,DI是IoC的一种实现

        就像我今天心情比较好,想吃顿大餐奖励自己,那么 “吃大餐” 就是思想和目标(是IoC),但最后我是吃什么大餐,肯德基还是海底捞等等,这个就是具体实现,就是DI。


都看到这了,点个赞再走吧,谢谢谢谢谢

这篇关于Spring IoCDI (1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/962657

相关文章

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

Java利用docx4j+Freemarker生成word文档

《Java利用docx4j+Freemarker生成word文档》这篇文章主要为大家详细介绍了Java如何利用docx4j+Freemarker生成word文档,文中的示例代码讲解详细,感兴趣的小伙伴... 目录技术方案maven依赖创建模板文件实现代码技术方案Java 1.8 + docx4j + Fr

SpringBoot首笔交易慢问题排查与优化方案

《SpringBoot首笔交易慢问题排查与优化方案》在我们的微服务项目中,遇到这样的问题:应用启动后,第一笔交易响应耗时高达4、5秒,而后续请求均能在毫秒级完成,这不仅触发监控告警,也极大影响了用户体... 目录问题背景排查步骤1. 日志分析2. 性能工具定位优化方案:提前预热各种资源1. Flowable

基于SpringBoot+Mybatis实现Mysql分表

《基于SpringBoot+Mybatis实现Mysql分表》这篇文章主要为大家详细介绍了基于SpringBoot+Mybatis实现Mysql分表的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可... 目录基本思路定义注解创建ThreadLocal创建拦截器业务处理基本思路1.根据创建时间字段按年进

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La