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的学习正式开始

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

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

相关文章

c语言练习87:合并两个有序数组

合并两个有序数组 合并两个有序数组https://leetcode.cn/problems/merge-sorted-array/ 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff…

动态资源平衡:主流虚拟化 DRS 机制分析与 SmartX 超融合的实现优化

资源的动态调度是虚拟化软件(或超融合软件)中的一项重要功能,主要指在虚拟化集群中,通过动态改变虚拟机的分布,达到优化集群可用性的目标。这一功能以 VMware vSphere 发布的 Distributed Resource Scheduler&#xff…

day62:ARMday9,I2c总线通信

作业&#xff1a;按键中断实现LED1、蜂鸣器、风扇 key_in.c: #include "key_in.h"void gpio_init() {//RCC使能//GPIOERCC->MP_AHB4ENSETR | (0x1<<4);//GPIOBRCC->MP_AHB4ENSETR | (0x1<<1);//PE10、PB6、PE9输出模式GPIOE->MODER & ~(0…

AutoGPT:让 AI 帮你完成任务事情 | 开源日报 No.54

Significant-Gravitas/AutoGPT Stars: 150.4k License: MIT AutoGPT 是开源 AI 代理生态系统的核心工具包。它采用模块化和可扩展的框架&#xff0c;使您能够专注于以下方面&#xff1a; 构建 - 为惊人之作打下基础。测试 - 将您的代理调整到完美状态。查看 - 观察进展成果呈…

基于SpringBoot的网上订餐系统

基于SpringBoot的网上订餐系统的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 【主要功能】 角色&#xff1a;用户、管理员管理员&#xff1a;登录、个人中心、会员管理、…

TensorFlow入门(十二、分布式训练)

1、按照并行方式来分 ①模型并行 假设我们有n张GPU,不同的GPU被输入相同的数据,运行同一个模型的不同部分。 在实际训练过程中,如果遇到模型非常庞大,一张GPU不够存储的情况,可以使用模型并行的分布式训练,把模型的不同部分交给不同的GPU负责。这种方式存在一定的弊端:①这种方…

sklearn处理离散变量的问题——以决策树为例

最近做项目遇到的数据集中&#xff0c;有许多高维类别特征。catboost是可以直接指定categorical_columns的【直接进行ordered TS编码】&#xff0c;但是XGboost和随机森林甚至决策树都没有这个接口。但是在学习决策树的时候&#xff08;无论是ID3、C4.5还是CART&#xff09;&am…

嵌入式养成计划-40----C++菱形继承--虚继承--多态--模板--异常

九十四、菱形继承 94.1 概念 菱形继承又称为钻石继承&#xff0c;是由公共基类派生出多个中间子类&#xff0c;又由中间子类共同派生出汇聚子类&#xff0c;汇聚子类会得到多份中间子类从公共基类继承下来的数据成员&#xff0c;会造成空间浪费&#xff0c;没有必要。 所以存…

工程师必须记住的电路元件符号及英语翻译

很多电子小白第一次接触印刷电路板&#xff08;PCB&#xff09;时&#xff0c;总会头痛那些密密麻麻的元件字母符号&#xff0c;这些电路元件符号基本上都是采用英语缩写&#xff0c;下面我们来看看这些电路元件的英语符号有哪些&#xff1f; 电阻器&#xff08;Resistor&#…

C++入门指南:类和对象总结友元类笔记(下)

C入门指南:类和对象总结友元类笔记&#xff08;下&#xff09; 一、深度剖析构造函数1.1 构造函数体赋值1.2 初始化列表1.3 explicit关键字 二、static成员2.1 概念2.2 特性 三、友元3.1 友元函数3.2 友元类 四、 内部类4.1 概念4.2 特征 五、拷贝对象时的一些编译器优化六、深…

Linux进阶-加深进程印象

目录 进程 进程状态转换 进程状态 启动新进程 system()函数 system.c文件 Makefile文件 执行过程 fork()函数 函数原型 fork.c文件 Makefile文件 执行过程 exec系列函数 函数原型 execl.c文件 Makrfile文件 执行过程 终止进程 exit()函数和_exit()函数 头…

机器人制作开源方案 | 杠杆式6轮爬楼机器人

1. 功能描述 本文示例将实现R281b样机杠杆式6轮爬楼机器人爬楼梯的功能&#xff08;注意&#xff1a;演示视频中为了增加轮胎的抓地力&#xff0c;在轮胎上贴了双面胶&#xff0c;请大家留意&#xff09;。 2. 结构说明 杠杆式6轮爬楼机器人是一种专门用于爬升楼梯或不平坦地面…

【elasticsearch】elasticsearch8.0.1使用rpm包安装并启用TLS

背景 公司的业务需要在加密的情况下使用&#xff0c;为此&#xff0c;研究测试了一下es8是如何启用TLS的。以下是测试使用过程。 x-pack了解 在 Elasticsearch 7.11.0 版本及更高版本中&#xff0c;X-Pack 功能在默认情况下已经整合到 Elastic Stack 的各个组件中&#xff0…

M2芯片的Mac上安装Linux虚拟机——提前帮你踩坑

M2芯片的Mac上安装Linux虚拟机——提前帮你踩坑 1. 前言1.1 系统说明1.2 Linux系统选择——提前避坑1.3 下载vmware_fusion1.3.1 官网下载1.3.2 注册 CAPTCHA验证码问题1.3.3 产品说明 1.4 下载操作系统镜像1.4.1 下载centos&#xff08;如果版本合适的&#xff09;1.4.2 下载…

Excel 自动提取某一列不重复值

IFERROR(INDEX($A$1:$A$14,MATCH(0,COUNTIF($C$1:C1,$A$1:$A$14),0)),"")注意&#xff1a;C1要空置&#xff0c;从C2输入公式 参考&#xff1a; https://blog.csdn.net/STR_Liang/article/details/105182654 https://zhuanlan.zhihu.com/p/55219017?utm_id0

c++视觉处理---直方图均衡化

直方图均衡化 直方图均衡化是一种用于增强图像对比度的图像处理技术。它通过重新分布图像的像素值&#xff0c;以使图像的直方图变得更均匀&#xff0c;从而提高图像的视觉质量。在OpenCV中&#xff0c;您可以使用 cv::equalizeHist 函数来执行直方图均衡化。以下是 cv::equal…

06-Zookeeper选举Leader源码剖析

上一篇&#xff1a;05-Zookeeper典型使用场景实战 一、为什么要看源码 提升技术功底&#xff1a;学习源码里的优秀设计思想&#xff0c;比如一些疑难问题的解决思路&#xff0c;还有一些优秀的设计模式&#xff0c;整体提升自己的技术功底深度掌握技术框架&#xff1a;源码看多…

Jenkins更换主目录

Jenkins储存所有的数据文件在这个目录下. 你可以通过以下几种方式更改&#xff1a; 使用你Web容器的管理工具设置JENKINS_HOME环境参数.在启动Web容器之前设置JENKINS_HOME环境变量.(不推荐)更改Jenkins.war(或者在展开的Web容器)内的web.xml配置文件. 这个值在Jenkins运行时…

ExcelBDD Python指南

在Python里面支持BDD Excel BDD Tool Specification By ExcelBDD Method This tool is to get BDD test data from an excel file, its requirement specification is below The Essential of this approach is obtaining multiple sets of test data, so when combined with…

【【萌新的SOC学习之自定义IP核 AXI4接口】】

萌新的SOC学习之自定义IP核 AXI4接口 自定义IP核-AXI4接口 AXI接口时序 对于一个读数据信号 AXI突发读 不要忘记 最后还有拉高RLAST 表示信号的中止 实验任务 &#xff1a; 通过自定义一个AXI4接口的IP核 &#xff0c;通过AXI_HP接口对PS端 DDR3 进行读写测试 。 S_AXI…