• 什么是Spring,Spring的核心和设计思想你了解吗?


    目录

    1.初识Spring 

    1.1 什么是容器

    1.2 什么是IoC

    2.什么是IoC容器.

    2.1 什么是DI


    哈喽呀,你好呀,欢迎呀,快来看一下这篇宝藏博客吧~~~


    1.初识Spring 

    Srping指的是Spring Framework(Spring 框架).我们经常会听见框架二字,其中java中最最主流的框架当属Spring.Spring是一个开源框架,有着活跃且庞大的社区.那说了这么多,Spring框架又是什么呢,又有什么作用呢?

    再具体一点来说,Spring框架就是一个包含了众多工具方法的IoC容器.基于这个容器,Java企业级的开发可以变得更简单.那么问题又来了,IoC容器又是什么呢?

    1.1 什么是容器

    了解IoC容器之前,我们得先了解一下什么是容器.在java中,应该了解List/Map吧,List/Map就是一个数据存储的容器.还有Tomcat,它就是一个web容器.所以啊,容器啊,其实就和它字面上的意思差不多,就是用来容纳某种物品的装置,可放可取.List/Map存放的是一些数据,有些网站就是运行在tomcat这个容器上.那IoC容器具体是干嘛的呢?

    1.2 什么是IoC

    IoC全称Inversion of Control,翻译成中文就是"控制反转"的意思.也就是说Spring是一个"控制反转"的容器.怎么理解这个"控制反转"呢,我们先来看一个例子:

    比如我现在要造一辆车:

    第一种思想就是造车需要依赖车身,车身需要依赖底盘,底盘需要依赖轮胎.大致流程如下图:

    代码实现:

    1. public class NewCar {
    2. public static void main(String[] args) {
    3. Car car = new Car();
    4. car.init();
    5. }
    6. /**
    7. * 汽⻋对象
    8. */
    9. static class Car {
    10. public void init() {
    11. // 依赖⻋身
    12. Framework framework = new Framework();
    13. framework.init();
    14. }
    15. }
    16. /**
    17. * ⻋身类
    18. */
    19. static class Framework {
    20. public void init() {
    21. // 依赖底盘
    22. Bottom bottom = new Bottom();
    23. bottom.init();
    24. }
    25. }
    26. /**
    27. * 底盘类
    28. */
    29. static class Bottom {
    30. public void init() {
    31. // 依赖轮胎
    32. Tire tire = new Tire();
    33. tire.init();
    34. }
    35. }
    36. /**
    37. * 轮胎类
    38. */
    39. static class Tire{
    40. private int size = 20;
    41. public void init() {
    42. System.out.println("轮胎尺⼨:" + size);
    43. }
    44. }
    45. }

    按照上诉思想,我们确实是可以实现一辆车的构造的.但是仔细想一下,我现在的车的轮胎尺寸是固定的,随着用户需求的增大,轮胎的尺寸需求可能不一样,这时,我们就需要改变一下代码了:

    1. public class NewCar2 {
    2. public static void main(String[] args) {
    3. Car car = new Car(20);
    4. car.run();
    5. }
    6. /**
    7. * 汽⻋对象
    8. */
    9. static class Car {
    10. private Framework framework;
    11. public Car(int size) {
    12. framework = new Framework(size);
    13. }
    14. public void run() {
    15. // 依赖⻋身
    16. framework.init();
    17. }
    18. }
    19. /**
    20. * ⻋身类
    21. */
    22. static class Framework {
    23. private Bottom bottom;
    24. public Framework(int size) {
    25. bottom = new Bottom(size);
    26. }
    27. public void init() {
    28. // 依赖底盘
    29. bottom.init();
    30. }
    31. }
    32. /**
    33. * 底盘类
    34. */
    35. static class Bottom {
    36. private Tire tire;
    37. public Bottom(int size) {
    38. tire = new Tire(size);
    39. }
    40. public void init() {
    41. // 依赖轮胎
    42. tire.init();
    43. }
    44. }
    45. /**
    46. * 轮胎类
    47. */
    48. static class Tire {
    49. // 尺⼨
    50. private int size;
    51. public Tire(int size) {
    52. this.size = size;
    53. }
    54. public void init() {
    55. System.out.println("轮胎尺⼨:" + size);
    56. }
    57. }
    58. }

    对比一下这两段代码,我们可以发现,就新增轮胎尺寸这一小改动,这个车的整个链就都要发生改动.

    以上仅仅只是改动了轮胎的尺寸,但是随着用户需求的多样化,比如对轮胎的材质,样式等等可能会有各种各样的要求,每一个小的改动都会触发整个链,显然,这就加大了成本.那有没有另外一种思想,当我们修改底层代码时,不会影响到其他的业务代码呢?要找到另一种更好的方法,我们就要分析一下,为什么当前代码不太好.通过观察我们可以发现,一环扣一环是因为每一个类中都new了自己依赖的一个下级类,当下级类改变时,上级类就需要做出相应的更改.故这样的设计就会导致下级出现问题,上级就要进行修改.

    所以为了降低它这个耦合度,我们就可以用以下这个方法:

    我们不再在类中new一个它所依赖的下级类了,而是将下级类主动的传进去(也就是注入),按照这种方法,我们就不需要将new它的下级类,这样下级类改不改变都不会影响我当前类的设计.就成功完成了解耦.

    按照以上的思路,我们将创建下级对象改为注入传递下级对象的方式,代码如下:

    1. public class NewCar3 {
    2. public static void main(String[] args) {
    3. Tire tire = new Tire(20);
    4. Bottom bottom = new Bottom(tire);
    5. Framework framework = new Framework(bottom);
    6. Car car = new Car(framework);
    7. car.run();
    8. }
    9. static class Car {
    10. private Framework framework;
    11. public Car(Framework framework) {
    12. this.framework = framework;
    13. }
    14. public void run() {
    15. framework.init();
    16. }
    17. }
    18. static class Framework {
    19. private Bottom bottom;
    20. public Framework(Bottom bottom) {
    21. this.bottom = bottom;
    22. }
    23. public void init() {
    24. bottom.init();
    25. }
    26. }
    27. static class Bottom {
    28. private Tire tire;
    29. public Bottom(Tire tire) {
    30. this.tire = tire;
    31. }
    32. public void init() {
    33. tire.init();
    34. }
    35. }
    36. static class Tire {
    37. private int size;
    38. public Tire(int size) {
    39. this.size = size;
    40. }
    41. public void init() {
    42. System.out.println("轮胎:" + size);
    43. }
    44. }
    45. }

    上述代码可以看出,我们没有在类中创建它所需要的对象了,而是将它所需要的对象传递了进来.

    无论底层怎样改变,整个调用链都不需要做任何更改的,这就使我们的设计更灵活了.用图来表示就是:

    •  对比总结规律:

    第一种思想中对象创建顺序是:Car -> Framework -> Bottom -> Tire

    第二种思想的对象创建顺序是:Tire -> Bottom -> Framework -> Car

    从这张图片我们就可以看出,这两种设计方法对类的创建恰恰是相反的.第一种思想是:先创建汽车类,再由汽车类创建并控制车身类,然后车身类创建并控制底盘类,依次向下,直到底层.也就是说,由当前类创建并控制下级类的,依次向下,直到底层,环环相扣.而第二种思想是与第一种截然不同的是,将这种从上到下的控制权进行了反转.也就是说,下级类不再由当前类所创建了,而是下级类自己主动注入到当前类中.这样下级类就摆脱了当前类的控制,故下级类无论怎样变,都不会影响到当前类了,这就是典型的控制反转,也就是IoC的实现思想.

    2.什么是IoC容器.

    还是回到我们最开始的这句话上:Spring是一个包含了众多工具的IoC(控制反转)容器.至于这个"众多工具"我以后再讲,现在可以粗略的理解为具有很多功能.控制反转相信大家通过上述造车的例子已经有所了解了,就是通过注入"属性"的方法.将控制权反转.

    Spring是一个包含了众多工具的IoC容器,这句话归根结底,就还是"容器"二字.既然是"容器",那它就具备两个最基本的功能:

    1. 将对象存入容器
    2. 从容器中取出对象

    所以我们要学习Spring最核心的功能就是,就是如何将对象存储到容器中,再从Spring中将对象取出来.

    IoC容器和普通程序开发的区别:

    将对象存储到IoC容器中就相当于我们在做一项工程时,将需要的工具都先存放在仓库里面.需要的时候直接取就行了,用完了再放回去.而之前new 对象的方式就相当于需要的时候就现做,用完了就销毁,某个时候又需要的话就再重新创建.这就是IoC容器和普通程序开发的区别.从中我们也可以发现IoC的优势之处.

    Spring是一个IoC容器,说的是对象的创建和销毁都交给Spring来控制了.它本身又具有存储对象和获取对象的权利.

    2.1 什么是DI

    说到IoC就不得不提到DI(Dependency Injection),翻译成中文就是"依赖注入"的意思.

    依赖注入:就是在IoC运行期间,动态的将某种依赖关系注入到组件之中,它是Spring框架核心IoC技术的具体实现.DI和IoC技术是从不同角度去描述同一件事.就是指通过引入IoC容器,利用依赖注入的方式,实现对象之间的解耦.

    IoC是一种思想,可以理解为一种指导原则,但是最终还需要有可行的方案.而DI就是这个方案的具体实现.

    比如我现在想减肥,那个"减肥"就是一种思想(是IoC),而我最后是通过跑步还是跳绳来减减肥呢?这就是具体的而实现,就是DI.

    好啦,看到这里就结束啦,考考你,以下问题都会了吗:

    • Spring是什么?如何理解Spring?
    • IoC和DI是什么?有什么区别?
    • Spring最核心的功能时还是啥呢?

    如果答不上来,就再看一下这篇博客吧~~

  • 相关阅读:
    R语言绘制IPCC风格箱线抖动点图
    Linux内核分析(六)--处理器调度基本准则和实现介绍
    Springboot整合常见日志框架
    GITEE 基于OAuth2的API V5版本
    【python入门】异常、文件操作
    SAML2.0 笔记(二)
    正则表达式基本语法
    1. OSPF 基础实验(二):多区域
    项目管理过程中要用到的132个工具和技术
    天书夜读笔记——内存分页机制
  • 原文地址:https://blog.csdn.net/m0_63039919/article/details/127908301