当前位置: 首页 > news >正文

Spring是什么?为什么要使用Spring?

目录

前言

一、Spring是什么?

1.1 轻量级

1.2 JavaEE的解决方案

二、为什么要使用Spring

2.1 传统方式完成业务逻辑

2.2 使用Spring模式完成业务逻辑

三、为什么使用Spring?


前言

本文主要介绍Spring是什么,并且解释为何要去使用Spring,通过一个实际的案例来展示了Spring的强大之处。通过本章正式开始Spring的学习!


一、Spring是什么?

Spring是一个轻量级的Java企业开发的解决方案,整合了许多优秀的设计模式。

1.1 轻量级

  • 对于运行环境是没有要求的

        开源的可以,收费的也可以

  • 代码的移植性高

        不要实现额外的接口

1.2 JavaEE的解决方案

为什么说Spring是JavaEE中的解决方案呢,在项目开发的过程中类似于Mybatis这种框架只是针对于DAO这一层进行操作,但是Spring对每一个层次都有相对的解决方案,所以这里称Spring为JavaEE中的解决方案。

二、为什么要使用Spring

2.1 传统方式完成业务逻辑

上面只是简单的介绍了一下Spring,对于Spring详细介绍后面再来分析,接下来就分析一下为什么要使用Spring。

对于传统的创建对象的模式,我们是通过直接new对象的方式。假设我现在有一个User类,我要通过UserDao类进行业务操作,然后通过UserService对UserDao类进行控制操作。那么传统的方法就是一步一步的new对象。

1)首先,创建一个User类

public class User {private String id;private String name;
}

2)在UserDao中写出相应的业务操作

public class UserDao {public void login(String name, String password) {// 这里本来是需要写crud的具体操作的,但是为了演示方便就不写了System.out.println("name:"+name+",password:"+password);}
}

3)在UserService中进行相应的操作

public class UserService {UserDao userDao = new UserDao();public void login(String name, String password) {userDao.login(name, password);}
}

4)进行测试,模拟登录的过程

@org.junit.Test
public void test() {UserService userService = new UserService();User user = new User("张三","123456");userService.login(user);
}

此时该业务逻辑就完成了 

假设这个时候UserService过时了,我想重新写一个UserServiceNew来操作业务逻辑,对于传统的方式可能就需要对代码进行修改。但是在项目中对代码进行了修改,就意味着要重新测试并部署。

@org.junit.Test
public void test() {//UserService userService = new UserService(); UserServiceNew userServiceNew = new UserServiceNew();User user = new User("张三","123456");//userService.login(user);userServiceNew.login(user);
}

2.2 使用Spring模式完成业务逻辑

 此时就涉及解耦合,那么什么是耦合呢?

耦合:指定是代码之间的强联系关系,一方的改变就会影响到另一方

  • 不利于代码的维护
  • 将类硬编码在程序中

接下来就使用Spring模式再对上述业务逻辑进行操作。在测试的过程中,就不new Service对象了而是使用工厂模式去生产Service对象,这样可以解耦

创建一个工厂类

public class BeanFactory {public static UserService getUserService() {return new UserService();}
}

 此时利用工厂类再去创建UserService对象

@org.junit.Test
public void test() {//UserService userService = new UserService();UserService userService = BeanFactory.getUserService();User user = new User("张三","123456");userService.login(user);
}

这时候细心的同学可能就发现了,工厂类中也是new对象啊,那不还是有耦合。确实是这样的,接下来就对工厂类继续修改(由于测试流程是一致的,这里就不在展示测试过程)

public class BeanFactory {public static UserService getUserService() {// 这里使用反射创建对象UserService userService = null;try {Class clazz = Class.forName("com.gl.demo.UserService");userService = (UserService) clazz.newInstance();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return userService;}
}

此时使用反射创建类对象大大降低了耦合,但是再细心一点的同学就会发现,那要是这个类名称变化了呢,这个代码还不是要修改 。说的对,接下来就是重头戏了,使用文件加载的方式加载类对象!

public class BeanFactory {// 创建文件对象private static Properties env = new Properties();// 利用静态代码块一次性的加载文件static {InputStream inputStream = BeanFactory.class.getResourceAsStream("/applicationContext.properties");try {env.load(inputStream);inputStream.close();} catch (IOException e) {e.printStackTrace();}}public static UserService getUserService() {UserService userService = null;try {Class clazz = Class.forName(env.getProperty("userService"));userService = (UserService) clazz.newInstance();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return userService;}
}

此时回看代码,耦合基本上就没有了,如果要添加类的话,也只需要更改文件中的类路径就行了

三、为什么使用Spring?

对于类对象,不只是单单的存在一个UserService,回看UserService方法,也是new了一个UserDao对象。肯定也是存在耦合的,这里肯定也要利用工厂类获取

此时在UserService中使用BeanFactory工厂类创建UserDao对象,并且在BeanFactory中创建对应的方法获取UserDao对象

public class BeanFactory {// 创建文件对象private static Properties env = new Properties();// 利用静态代码块一次性的加载文件static {InputStream inputStream =BeanFactory.class.getResourceAsStream("/applicationContext.properties");try {env.load(inputStream);inputStream.close();} catch (IOException e) {e.printStackTrace();}}public static UserDao getUserDao() {UserDao userDao = null;try {Class clazz = Class.forName(env.getProperty("userDao"));userDao = (UserDao) clazz.newInstance();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return userDao;}public static UserService getUserService() {UserService userService = null;try {Class clazz = Class.forName(env.getProperty("userService"));userService = (UserService) clazz.newInstance();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return userService;}
}

此时,问题又出现了,每当需要获取一个对象的时候我都要写一个方法,那这样的代码冗余不是非常高吗!此时就可以使用Object来返回对象解决此问题!

public class BeanFactory {// 创建文件private static Properties env = new Properties();// 利用静态代码块一次性的加载文件static {InputStream inputStream =BeanFactory.class.getResourceAsStream("/applicationContext.properties");try {env.load(inputStream);inputStream.close();} catch (IOException e) {e.printStackTrace();}}// 此时就利用参数获取想要创建的对象public static Object getBean(String key) {Object ret = null;try {Class clazz = Class.forName(env.getProperty(key));ret = clazz.newInstance();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}return ret;}//    public static UserService getUserService() {
//        UserService userService = null;
//        try {
//            Class clazz = Class.forName(env.getProperty("userService"));
//            userService = (UserService) clazz.newInstance();
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        } catch (InstantiationException e) {
//            e.printStackTrace();
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        }
//        return userService;
//    }
//
//    public static UserDao getUserDao() {
//        UserDao userDao = null;
//        try {
//            Class clazz = Class.forName(env.getProperty("userDao"));
//            userDao = (UserDao) clazz.newInstance();
//        } catch (ClassNotFoundException e) {
//            e.printStackTrace();
//        } catch (InstantiationException e) {
//            e.printStackTrace();
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        }
//        return userDao;
//    }}

对于之前的类对象获取也需要进行相应的处理,强制类型转化即可。

至此,所有的问题都已经解决完毕了!!! 从上面的过程可以发现,解耦的过程还是很复杂的,但是在Spring中已经包含了工厂的设计模式!并不需要我们去手动的写工厂类,我们只需要去使用Spring中的工厂类就可以了。Spring 框架提供了许多功能和特性,可以帮助开发人员快速构建企业应用程序。所以这也就是我们为什么要使用Spring进行项目开发的原因!

这里Spring的本质也就可以总结为:工厂!一个功能强大的工厂!至此Spring的学习正式开始

相关文章:

Spring是什么?为什么要使用Spring?

目录 前言 一、Spring是什么? 1.1 轻量级 1.2 JavaEE的解决方案 二、为什么要使用Spring 2.1 传统方式完成业务逻辑 2.2 使用Spring模式完成业务逻辑 三、为什么使用Spring? 前言 本文主要介绍Spring是什么,并且解释为何要去使用Spring&…...

自我监督学习日志

学习日志 10.12 一天学不了一分钟,不知道为什么也就是了 今天一定要学一个小时! 机器学习就是机器帮我们找一个函数 语音辨识,语音,声音讯号 转化为文字 帮我们找一个人类写不出来的复杂函数 类神经网络 输入 一张图片用一个矩…...

配置CA证书

前置条件 配置Java环境变量。 具体操作 windows环境 以管理员方式执行CMD窗口,输入命令; cd /d %JAVA_HOME%\jre\lib\securitycurl -kv https://xxx/artifactory/CMC-Release/certificates/xxxRootCA.cer -o xxxRootCA.cercurl -kv https://xxx/art…...

计算机毕业设计选什么题目好?springboot 高校就业管理系统

✍✍计算机编程指导师 ⭐⭐个人介绍:自己非常喜欢研究技术问题!专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目:有源码或者技术上的问题欢迎在评论区一起讨论交流! ⚡⚡ Java实战 |…...

上海-华为全联接大会|竹云受邀参加华为云ROMAConnect行业生态联盟成立联合发布会

2023年9月22日,在上海举办的华为全联接大会上,竹云作为华为云全方位合作伙伴代表,受邀参加华为云ROMAConnect行业生态联盟成立联合发布会。华为云PaaS服务产品部副部长张甲磊以及联盟主要成员企业出席发布仪式,共同见证华为云ROMA…...

走进GraalVM

是什么 GraalVM是一个高性能的JDK,旨在加速用Java和其他JVM语言编写的应用程序的执行,同时还为JavaScript,Python,Ruby和许多其他流行语言提供运行特点 GraalVM可以代替JDK、JVM之前的工作。 GraalVM除了支持Java,也支…...

spark读取hive表字段,区分大小写问题

背景 spark任务读取hive表,查询字段为小写,但Hive表字段为大写,无法读取数据 问题错误: 如何解决呢? In version 2.3 and earlier, when reading from a Parquet data source table, Spark always returns null for any column …...

UE4和C++ 开发-头文件(.h) 和实现文件(.cpp)区别

.h文件和.cpp文件是C程序中的两种不同类型的文件。 .h文件通常包含类、函数和变量的声明, 而.cpp文件包含这些声明的实现。 .h文件中的声明通常是公共的,可以被其他文件包含和使用。.cpp文件中的实现通常是私有的,只能在该文件中使用。 在…...

git介绍和安装、(git,github,gitlab,gitee介绍)、git工作流程、git常用命令、git忽略文件

1 git介绍和安装 2 git,github,gitlab,gitee介绍 3 git工作流程 4 git常用命令 5 git忽略文件 1 git介绍和安装 首页功能写完了---》正常应该提交到版本仓库---》大家都能看到这个---》 运维应该把现在这个项目部署到测试环境中---》测试…...

go cpu、内存监控、性能分析:PProf

PProf PProf 是什么 PProf是 golang 官方提供的性能调优分析工具,用于分析和优化Go程序的性能。 PProf通过收集和分析程序的运行时数据来生成性能分析报告。它使用Go语言的运行时特性,如代码注释和特殊的程序运行标记,来收集性能数据。PPr…...

计算机网络传输层知识总结·

传输层提供的服务 传输层的功能 ●传输层提供进程之间的逻辑通信,即端到端的通信 ●复用和分用 ●差错检测(首部和数据部分) ●面向连接的TCP和无连接的UDP 端口的作用 ●端口标识的是主机中的进程 ●硬件端口是不同…...

vue使用ant design Vue中的a-select组件实现下拉分页加载数据

<a-form-model-item :labelCol"labelCol" :wrapperCol"wrapperCol" prop"equipmentTypeId" label"所属设备种类"> <a-select v-model"model.equipmentTypeId" popupScroll"handlePopupScroll" placehold…...

精准突击!GitHub星标103k,2023年整理1658页JAVA秋招面试题

前言&#xff1a; 现在的互联网开发岗招聘&#xff0c;程序员面试背八股文已经成为了不可逆转的形式&#xff0c;其中一个Java岗几百人在投简历也已经成为了常态&#xff01;更何况一份面试题动辄七八百道&#xff0c;你吃透了&#xff0c;技术只要不是很差&#xff0c;面试怎…...

GEE:基于GLDAS数据集分析土壤湿度的时间序列变化

作者:CSDN @ _养乐多_ 本篇博客将介绍如何使用Google Earth Engine(GEE)进行土壤湿度数据的分析。我们将使用NASA GLDAS(Global Land Data Assimilation System)数据集,其中包括了关于土壤湿度的信息。通过该数据集,我们将了解土壤湿度在特定区域和时间段内的变化,并生…...

Nacos安装

Nacos安装 1.Windows安装 1.1.下载安装包 在Nacos的GitHub页面&#xff0c;提供有下载链接&#xff0c;可以下载编译好的Nacos服务端或者源代码&#xff1a; GitHub主页&#xff1a;https://github.com/alibaba/nacos GitHub的Release下载页&#xff1a;https://github.co…...

UE4和C++ 开发-C++与UMG的交互2(C++获取UMG的属性)

1、...C获取UMG的属性 1.1、第一种方法&#xff1a;通过名称获取控件。 void UMyUserWidget::NativeConstruct() {Super::NativeConstruct();//通过名字&#xff0c;获取蓝图控件中的按钮引用。CtnClic Cast<UButton>(GetWidgetFromName(TEXT("Button_44"))…...

Ubuntu 22.04.3 LTS单机私有化部署sealos

推荐使用奇数台 Master 节点和若干 Node 节点操作系统 :Ubuntu 22.04 LTS内核版本 :5.4 及以上配置推荐 :CPU 4 核 , 内存 8GB, 存储空间 100GB 以上最小配置 :CPU 2 核 , 内存 4GB, 存储空间 60GB 这里采用的Ubuntu 22.04.3 LTS 版本&#xff0c;Ubuntu 20.04.4 LTS这个版本…...

#力扣:2236. 判断根结点是否等于子结点之和@FDDLC

2236. 判断根结点是否等于子结点之和 一、Java /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNo…...

暴力递归转动态规划(九)

题目 题有点难&#xff0c;但还挺有趣 有一个咖啡机数组arr[]&#xff0c;其中arr[i]代表每一个咖啡机冲泡咖啡所需的时间&#xff0c;有整数N&#xff0c;代表着准备冲咖啡的N个人&#xff08;假设这个人拿到咖啡后喝完的时间为0&#xff0c;拿手里咖啡杯即变空&#xff09;&a…...

Linux知识点 -- 高级IO(一)

Linux知识点 – 高级IO&#xff08;一&#xff09; 文章目录 Linux知识点 -- 高级IO&#xff08;一&#xff09;一、5种IO模型1.IO再理解2.阻塞IO3.非阻塞轮询式IO4.信号驱动IO5.IO多路转接6.异步IO7.同步通信vs异步通信8.阻塞vs非阻塞 二、非阻塞IO1.设置非阻塞的方法2.非阻塞…...

Android AMS——内存回收机制(十二)

在 Android 中,AMS(Activity Manager Service)负责管理应用程序的生命周期和资源分配。其中,AMS也包含了内存回收机制,用于释放系统中不再使用的内存资源,以保证系统的稳定性和性能。 一、内存回收简介 1、回收机制 Android AMS 的内存回收机制主要涉及以下几个方面:…...

1600*C. Add One(数位DP找规律)

Problem - 1513C - Codeforces 解析&#xff1a; 考虑DP&#xff0c;DP[ i ] 为从 0 开始执行 i 次操作&#xff0c;此时数字的位数。 我们发现当一个9再操作一次就会变成1和0&#xff0c;并且相邻的大部分长度都不会变化&#xff0c;0会影响10次操作之后的位数&#xff0c;1会…...

干货丨送你几个实用PR编辑技巧(二) 优漫动游

小编认为无论看什么书或教程&#xff0c;都不应该脱离实际去学习PR技巧&#xff0c;基础理论与实践相结合&#xff0c;才能达到比较好的学习和应用效果。 技巧一 如果项目板里有很多素材&#xff0c;很难看清楚哪些素材是已经用过的&#xff0c;哪些是没用过的话&#xff0…...

[每周一更]-(第67期):docker-compose 部署php的laravel项目

容器化部署laravel框架的php项目 操作步骤 参考&#xff1a; https://www.cnblogs.com/jingjingxyk/p/16842937.htmlhttps://developer.aliyun.com/article/708976 0、plv项目修改 composer install.env 修改后台地址 IP:端口chmod -R 777 public / chmod -R 777 storagevi…...

vsCode 忽略 文件上传

1 无 .gitignore 文件时&#xff0c;在项目文件右键&#xff0c;Git Bash 进入命令行 输入 touch .gitignore 生成gitignore文件 2 、在文件.gitignore里输入 node_modules/ dist/ 来自于&#xff1a;vscode git提交代码忽略node_modules_老妖zZ的博客-CSDN博客...

197、管理 RabbitMQ 的虚拟主机

开启Rabbitmq的一些命令&#xff1a; 小黑窗输入&#xff1a; rabbitmq-plugins enable rabbitmq_management 启动控制台插件&#xff0c; 就是启动登录rabbitmq控制台的页面&#xff0c;rabbitmq_management 代表了RabbitMQ的管理界面。 rabbitmq-server 启动rabbitMQ服务器…...

[NCTF2019]SQLi regexp 盲注

/robots.txt 访问一下 $black_list "/limit|by|substr|mid|,|admin|benchmark|like|or|char|union|substring|select|greatest|%00|\|| |in|<|>|-|\.|\(\)|#|and|if|database|users|where|table|concat|insert|join|having|sleep/i";If $_POST[passwd] admi…...

通过webpack创建并打包js库到npm仓库

1.创建项目并进行基本配置 webpack配置文件&#xff1a; webpack.build.js const path require(path);module.exports {mode:development,entry:./src/webpack-numbers.js,output: {filename: webpack-numbers.js,path: path.resolve(__dirname, dist),clean: true,},}; p…...

【Java 进阶篇】深入了解JavaScript中的函数

函数是JavaScript编程中的核心概念之一。它们是可重用的代码块&#xff0c;可以帮助您组织和管理程序&#xff0c;使您的代码更具可读性和可维护性。在本篇博客中&#xff0c;我们将深入了解JavaScript中的函数&#xff0c;包括函数的基本语法、参数、返回值、作用域、闭包和高…...

谷歌 Chrome 浏览器正推进“追踪保护”功能

导读近日消息&#xff0c;根据国外科技媒体 Windows Latest 报道&#xff0c;谷歌计划在 Chrome 浏览器中推进“追踪保护”&#xff08;Tracking Protection&#xff09;功能&#xff0c;整合浏览器现有隐私功能&#xff0c;保护用户被网站跟踪。 根据一项 Chromium 提案&…...