首页 > 其他分享 >Spring学习记录之Spring启示录

Spring学习记录之Spring启示录

时间:2023-12-22 10:14:07浏览次数:33  
标签:依赖 记录 对象 Spring 代码 启示录 new 交出去

Spring学习记录之Spring启示录


前言

这篇文章是我第二次学习b站老杜spring相关课程所进行的学习记录,算是对课程内容及笔记的二次整理,以自己的理解方式进行二次记录,其中理解可能存在错误,欢迎且接受各位大佬们的批评指正;

学习视频地址:https://www.bilibili.com/video/BV1Ft4y1g7Fb/

视频配套笔记:https://www.yuque.com/dujubin/ltckqu/kipzgd?singleDoc# 《Spring6》 密码:mg9b


目录

目录


Spring启示录

一、阅读以下代码

UserController

public class UserController {

    private UserService userService = new UserServiceImpl();

    public void login(){
        String username = "admin";
        String password = "123456";
        boolean success = userService.login(username, password);
        if (success) {
            // 登录成功
        } else {
            // 登录失败
        }
    }
}

UserService

省略...

UserServiceImpl

public class UserServiceImpl implements UserService {

    private UserDao userDao = new UserDaoImplForMySQL();

    public boolean login(String username, String password) {
        User user = userDao.selectByUsernameAndPassword(username, password);
        if (user != null) {
            return true;
        }
        return false;
    }
}

UserDao

省略...

UserDaoImplForMySQL

public class UserDaoImplForMySQL implements UserDao {
    public User selectByUsernameAndPassword(String username, String password) {
        // 连接MySQL数据库,根据用户名和密码查询用户信息
        return null;
    }
}

二、分析上述代码存在的问题

如果用户表从MySql迁移到了Oracle(模拟开发需求变更)

我们需要再提供一个UserDao实现类UserDaoImplForOracle

public class UserDaoImplForOracle implements UserDao {
    public User selectByUsernameAndPassword(String username, String password) {
        // 连接Oracle数据库,根据用户名和密码查询用户信息
        return null;
    }
}

做完这一步之后,又因为我们在UserServiceImpl中引入了UserDaoImplForMySQL实现类对象,我们也需要切换其为UserDaoImplForOracle实现类对象。

很明显,以上的开发需求只是进行功能的扩展,添加了一个新的类UserDaoImplForOracle来应付数据库的变化(这样的操作在实际开发中是很常见的),但是对功能扩展的过程中引起了类间的连锁反应,这样的代码是耦合的、不易维护的。

其实这里有了解过面向对象编程的六大原则同学,也能看出这里违反了OCP开闭原则DIP依赖倒置原则

三、引出三种编程思想

这里借老杜的解释再阐述一下

① OCP开闭原则

开闭原则是这样说的:在软件开发过程中应当对扩展开放,对修改关闭。也就是说,如果在进行功能扩展的时候,添加额外的类是没问题的,但因为功能扩展而修改之前运行正常的程序,这是忌讳的,不被允许的。因为一旦修改之前运行正常的程序,就会导致项目整体要进行全方位的重新测试。这是相当麻烦的过程。导致以上问题的主要原因是:代码和代码之间的耦合度太高。如下图所示:

img

可以很明显的看出,上层是依赖下层的。UserController依赖UserServiceImpl,而UserServiceImpl依赖UserDaoImplForMySQL,这样就会导致下面只要改动上面必然会受牵连(跟着也会改),所谓牵一发而动全身。这样也就同时违背了另一个开发原则:依赖倒置原则

② DIP依赖倒置原则

依赖倒置原则(Dependence Inversion Principle),简称DIP,主要倡导面向抽象编程,面向接口编程,不要面向具体编程,让上层不再依赖下层,下面改动了,上面的代码不会受到牵连。这样可以大大降低程序的耦合度,耦合度低了,扩展力就强了,同时代码复用性也会增强。(软件七大开发原则都是在为解耦合服务

你可能会说,上面的代码已经面向接口编程了呀:

img

确实已经面向接口编程了,但对象的创建是:new UserDaoImplForOracle()显然并没有完全面向接口编程,还是使用到了具体的接口实现类。什么叫做完全面向接口编程?什么叫做完全符合依赖倒置原则呢?请看以下代码:

img

如果代码是这样编写的,才算是完全面向接口编程,才符合依赖倒置原则。那你可能会问,这样userDao是null,在执行的时候就会出现空指针异常呀。你说的有道理,确实是这样的,所以我们要解决这个问题。解决空指针异常的问题,其实就是解决两个核心的问题

  • 第一个问题:谁来负责对象的创建。【也就是说谁来:new UserDaoImplForOracle()/new UserDaoImplForMySQL()】
  • 第二个问题:谁来负责把创建的对象赋到这个属性上。【也就是说谁来把上面创建的对象赋给userDao属性】

如果我们把以上两个核心问题解决了,就可以做到既符合OCP开闭原则,又符合依赖倒置原则。

很荣幸的通知你:Spring框架可以做到。

在Spring框架中,它可以帮助我们new对象,并且它还可以将new出来的对象赋到属性上。换句话说,Spring框架可以帮助我们创建对象,并且可以帮助我们维护对象和对象之间的关系。比如:

img

Spring可以new出来UserDaoImplForMySQL对象,也可以new出来UserDaoImplForOracle对象,并且还可以让new出来的dao对象和service对象产生关系(产生关系其实本质上就是给属性赋值)。

很显然,这种方式是将对象的创建权/管理权交出去了,不再使用硬编码的方式了。同时也把对象关系的管理权交出去了,也不再使用硬编码的方式了。像这种把对象的创建权交出去,把对象关系的管理权交出去,被称为控制反转。

③ IoC控制反转

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计思想,可以用来降低代码之间的耦合度,符合依赖倒置原则。

控制反转的核心是:将对象的创建权交出去,将对象和对象之间关系的管理权交出去,由第三方容器来负责创建与维护。即不在程序中采用硬编码的方式来new对象了(把new对象的权力交出去),同时也不在程序中采用硬编码的方式来维护对象之间的关系了(对象之间关系的维护权也交出去了)。

控制反转常见的实现方式:依赖注入(Dependency Injection,简称DI)(补充强调:IoC是面向对象编程中的一种设计思想,DI是实现这种思想的一种方式。)

个人补充:在上述示例中我们讲到,不在类中自己去new对象,去使用该对象引用时一定会报空指针异常。所以我们要在使用该对象时让Spring自动将需要的对象实例赋值给改引用。一般情况下,我们给类中对象属性赋值时,一般采用两种方式,即一是通过构造方法给改对象引用赋值,二是调用该对象实例的set方法给对象引用赋值。所以Spring其实也是通过这两种方式去操作的。

通常,依赖注入的实现又包括两种方式:

  • set方法注入

  • 构造方法注入

而Spring框架就是一个实现了IoC思想的框架。

IoC可以认为是一种全新的设计模式,但是理论和时间成熟相对较晚,并没有包含在GoF中。(GoF指的是23种设计模式)

四、如何理解"依赖注入"

依赖注入中"依赖"是什么意思?

依赖其实就是对象和对象之间的关系。A<=>B<=>C

依赖注入中"注入"是什么意思?

注入是一种手段,通过这种手段,可以让对象之间产生依赖关系。

五、总结

到这里,我们就引出了学习Spring大概我们要解决的问题是什么,以及为什么要学Spring。很显然接下来我们就要学习哪些方法手段(代码写法)可以把对象的创建权交出去,把对象关系的管理权交出去,实现IoC控制反转。

标签:依赖,记录,对象,Spring,代码,启示录,new,交出去
From: https://www.cnblogs.com/zhao-XH/p/17920648.html

相关文章

  • 2023.12.22~ 做题记录
    1.ICPC2022Xi'anRABridge感觉很妙啊,应该不止蓝吧?首先一个转化是每次建桥操作就相当于交换两条链的后半部分,可以看看扶苏那篇题解的图。我们将每个点表示为形如\((x,y)\)的二元组表示它初始在第\(x\)行第\(y\)列,按\(y\)为键值排序,那么一次询问就是查询一条链的最......
  • 5分钟攻略Spring-Retry框架实现经典重试场景
    前言今天分享干货,控制了篇幅,5分钟内就能看完学会。主题是Spring-Retry框架的应用,做了一个很清晰的案例,代码可下载自测。框架介绍Spring-Retry框架是Spring自带的功能,具备间隔重试、包含异常、排除异常、控制重试频率等特点,是项目开发中很实用的一种框架。本篇所用框架的版本......
  • Ubuntu18下实时Linux内核的编译安装记录(保姆级)
    本人系统是虚拟机上的ubuntu18,过程参考了以下3个链接:https://blog.csdn.net/huangjunsheng123/article/details/116202848https://blog.51cto.com/u_15899439/5907513https://kunaly.blog.csdn.net/article/details/101111502?spm=1001.2101.3001.6650.3&utm_medium=distribute......
  • Spring-IOC
     1.前言1) 框架:spring的本质就是一个容器,放java对象的容器,java对象在spring容器中也叫做bean对象。项目启动的时候,把bean对象放到IOC容器中,当需要使用对象的时候,直接从容器中拿出来使用。2) 框架作用:提高开发效率;增强可重用性;提供编......
  • 【SpringBootWeb入门-17】Mybatis-基础操作-动态SQL
    1、章节回顾上一篇文章我们讲解完了Mybatis基础操作,本篇继续学习Mybatis中非常重要的功能:动态SQL。什么是动态SQL:随着用户的输入或外部条件的变化而变化的SQL语句,我们称为动态SQL。简单说SQL语句不是固定的,是动态变化的。就拿我们上一篇所提到的根据条件来查询员工的SQL语句来......
  • CF1912H Hypercatapult Commute记录
    题目链接:https://codeforces.com/problemset/problem/1912/H题意有\(n\)个城市,\(m\)个人。第\(i\)人想从城市\(a_i\)移动到\(b_i\)。每个城市每天可以使用至多一次传送胶囊,可以将任意数目的人从该城市传送到任意一个(相同的)其它城市。注意传送有时间顺序。求是否可以让......
  • 颓废记录
    [ARC117E]Zero-SumRanges2考虑分层对前缀和的折线\(dp\),发现每个“峰”会往下两边延伸形成一段,然后与另一个峰的相同结构撞上并终止,那么类似于[ZJOI2012]波浪地设计状态\(dp_{i,j,k}\)表示已经加入了\(i\)个点,当前有\(j\)段,匹配个数为\(k\)的方案数。转移时枚举下......
  • XILINX HLS 入坑记录 之 写RAM 综合出 读取+写入Ram
    最近使用XilinxHLS来开发算法的IPcore,使用的Vitis2021,发现光是EDA工具就存在很多的bug,比如:1.经常C综合停留在Usingflow_target'vivado'不给任何报错提示,永远卡死;2.点击coSimulationvivado启动后读取脚本卡死,不能正常仿真;3.C综合给出的资源使用和IPCore实现后......
  • Docker常用命令记录.......
    Docker基本命令查看本地镜像dockerimages搜索镜像dockersearchtomcat拉取镜像dockerpulltomcat:版本号#默认是latest删除镜像dockerrmiIMAGEID运行镜像-it表示与容器进行交互式启动-d表示可后台运行容器(守护式运行)--name给要运行的容器起的名字-......
  • Spring Boot学习随笔- 拦截器实现和配置(HandlerInterceptor、addInterceptors)、jar包
    学习视频:【编程不良人】2021年SpringBoot最新最全教程第十三章、拦截器拦截器:Interceptor拦截中断类似于javaweb中的Filter,不过没有Filter那么强大作用SpringMVC的拦截器是一种用于在请求处理过程中进行预处理和后处理的机制。拦截器可以在请求到达控制器之前和......