深入浅出 Spring:核心概念和基本用法详解

个人主页:17_Kevin-CSDN博客

收录专栏;《Java》


一、引言

在 Java 企业级应用开发中,Spring 框架已经成为了事实上的标准。它提供了一种轻量级的解决方案,使得开发者能够更轻松地构建灵活、可扩展的应用程序。在本文中,我们将探讨 Spring 框架的一些核心概念和基本用法,以此更好地理解和使用 Spring 进行开发。

二、依赖注入(DI)

在 Spring 中,依赖注入是一种设计模式,用于将对象之间的依赖关系解耦。它通过将依赖对象的创建和管理交给 Spring 容器来实现。这样,开发人员只需要关注业务逻辑,而不需要关心对象的创建和装配过程。

例如,在上面的学生管理系统中,我们可以使用依赖注入来注入学生服务对象到控制器中。通过在控制器的构造函数中添加学生服务对象作为参数,Spring 容器会在创建控制器实例时自动注入相应的学生服务对象。

public class StudentController {private final StudentService studentService;// 使用构造函数注入学生服务对象public StudentController(StudentService studentService) {this.studentService = studentService;}// 处理学生列表请求的方法@GetMapping("/students")public List<Student> listStudents() {return studentService.listAllStudents();}// 处理学生详情请求的方法@GetMapping("/students/{studentId}")public Student getStudent(@PathVariable int studentId) {return studentService.getStudentById(studentId);}// 处理学生创建请求的方法@PostMapping("/students")public void createStudent(@RequestBody Student student) {studentService.createStudent(student);}// 处理学生更新请求的方法@PutMapping("/students/{studentId}")public void updateStudent(@PathVariable int studentId, @RequestBody Student student) {studentService.updateStudent(studentId, student);}// 处理学生删除请求的方法@DeleteMapping("/students/{studentId}")public void deleteStudent(@PathVariable int studentId) {studentService.deleteStudent(studentId);}
}

在上述代码中,我们通过构造函数注入了学生服务对象到控制器中。这样,控制器就可以直接使用学生服务对象的方法来处理学生相关的请求。

三、控制反转(IOC)

除了依赖注入,Spring 还提供了控制反转的特性。控制反转是指将对象的控制权交给容器,而不是由对象自己来控制。在 Spring 中,容器负责创建和管理对象,以及将对象之间的依赖关系注入到相应的对象中。

例如,在上面的学生管理系统中,我们可以使用 Spring 的注解@Component将学生服务标注为一个 Spring 组件。这样,Spring 容器会在应用启动时自动创建学生服务对象,并将其注入到需要它的对象中。

// 学生服务接口
public interface StudentService {// 获取所有学生的方法List<Student> listAllStudents();// 获取指定学生的方法Student getStudentById(int studentId);// 创建学生的方法void createStudent(Student student);// 更新学生的方法void updateStudent(int studentId, Student student);// 删除学生的方法void deleteStudent(int studentId);
}// 学生服务实现类
@Component
public class StudentServiceImpl implements StudentService {// 学生列表private List<Student> students = new ArrayList<>();// 获取所有学生的方法@Overridepublic List<Student> listAllStudents() {return students;}// 获取指定学生的方法@Overridepublic Student getStudentById(int studentId) {return students.stream().filter(student -> student.getId() == studentId).findFirst().orElse(null);}// 创建学生的方法@Overridepublic void createStudent(Student student) {students.add(student);}// 更新学生的方法@Overridepublic void updateStudent(int studentId, Student student) {students.stream().filter(student1 -> student1.getId() == studentId).findFirst().ifPresentOrElse(student1 -> {student1.setName(student.getName());student1.setAge(student.getAge());},() -> {throw new RuntimeException("未找到要更新的学生");});}// 删除学生的方法@Overridepublic void deleteStudent(int studentId) {students.removeIf(student -> student.getId() == studentId);}
}

在上述代码中,我们使用@Component注解将学生服务实现类标注为一个 Spring 组件。这样,Spring 容器会在应用启动时自动创建学生服务对象,并将其注入到需要它的对象中。

四、AOP

除了依赖注入和控制反转,Spring 还提供了面向切面编程(AOP)的支持。AOP 允许我们将横切关注点(如日志记录、性能监控、事务管理等)与业务逻辑分离,从而提高代码的可维护性和可扩展性。

例如,在上面的学生管理系统中,我们可以使用 Spring 的 AOP 来添加日志记录功能。具体来说,我们可以创建一个日志切面类,并在其中添加日志记录的代码。然后,我们可以使用 Spring 的@Aspect注解将日志切面类标注为一个 Spring 组件,并使用@Pointcut注解指定要在哪些方法上应用日志记录。

// 日志切面类
@Aspect
@Component
public class LoggingAspect {// 记录日志的方法@Before("execution(* com.example.springstudent.service..*.*(..))")public void logBeforeMethod(JoinPoint joinPoint) {String className = joinPoint.getTarget().getClass().getName();String methodName = joinPoint.getSignature().getName();System.out.println("方法 " + className + "." + methodName + " 被调用");}// 记录日志的方法@After("execution(* com.example.springstudent.service..*.*(..))")public void logAfterMethod(JoinPoint joinPoint) {String className = joinPoint.getTarget().getClass().getName();String methodName = joinPoint.getSignature().getName();System.out.println("方法 " + className + "." + methodName + " 执行完毕");}
}

在上述代码中,我们使用@Component注解将日志切面类标注为一个 Spring 组件。然后,我们使用@Aspect注解将日志切面类标注为一个 Spring 切面。在@Pointcut注解中,我们指定要在所有学生服务接口和实现类的方法上应用日志记录。在@Before注解中,我们添加了一个前置通知,用于在方法执行之前记录日志。在@After注解中,我们添加了一个后置通知,用于在方法执行完毕后记录日志。

五、总结

通过本文,我们了解了 Spring 框架的一些核心概念和基本用法。Spring 提供了一种轻量级的解决方案,使得开发企业级应用程序更加简单和高效。

感谢您的阅读,希望这篇博客对你有所帮助。


 

I'm Kevin, and we'll see you in the next blog

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

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

相关文章

基于springboot+vue实现艺术水平考级报名系统【项目源码+论文说明】计算机毕业设计

基于springbootvue实现艺术水平考级报名系统演示 摘要 本次毕业设计基于SpringBoot框架开发了一款艺术水平考级报名管理系统。该系统为考生提供了线上报名、准考证管理等核心功能&#xff0c;并为系统管理员提供了在线发布考试信息、对报名考生进行审核等管理功能。通过该系统…

每日OJ题_简单多问题dp⑥_力扣714. 买卖股票的最佳时机含手续费

目录 力扣714. 买卖股票的最佳时机含手续费 状态机分析 解析代码 力扣714. 买卖股票的最佳时机含手续费 714. 买卖股票的最佳时机含手续费 难度 中等 给定一个整数数组 prices&#xff0c;其中 prices[i]表示第 i 天的股票价格 &#xff1b;整数 fee 代表了交易股票的手续…

ffmpeg6.0从demux_decode.c源码探索解封装流程

前言 在播放器的播放视频、音视频媒体文件的推流等实际应用中,解封装(demux)这个操作是不可避免的,也是最基础的操作。 拿播放器播放MP4来说,如果想实现播放器视频画面的播放和音频声音的播放都需要经过这个解封装的步骤。因为MP4是一种媒体文件格式,是一种封装格式,M…

快速高效地数据分析处理:QtiPlot for Mac中文直装版 兼容M

QtiPlot 是一个用于数据分析和可视化的跨平台科学应用程序。由于其多语言支持&#xff0c;QtiPlot 被积极用于世界各地学术机构的教学。许多研究科学家信任 QtiPlot 来分析他们的数据并发布他们的工作结果。来自各个科学领域和行业的数千名注册用户已经选择了 QtiPlot 来帮助他…

一文全面了解向量数据库

1. 什么是向量数据库&#xff1f;** 首先&#xff0c;我们需要理解什么是向量&#xff1f; 向量是基于不同特征或属性来描述对象的数据表示。每个向量代表一个单独的数据点&#xff0c;例如一个词或一张图片&#xff0c;由描述其许多特性的值的集合组成。这些变量有时被称为“…

C/C++火柴棍等式

有n根(n<24)火柴棍&#xff0c;你可以拼出多少个形如“ABC"的等式?等式中的A、B、C是用火柴棍拼出的整数(若该数非零&#xff0c;则最高位不能是0)。用火柴棍拼数字0-9的拼法如图所示: 依次需要用到的火柴棍数目为6 2 5 5 4 5 6 3 7 6 。 如果是初学者可能会这么写。 …

数据结构:基于数组实现简单的数据缓存区(简单队列)

1 前言 在我们使用CAN或者以太网调试时&#xff0c;经常需要缓存最近n次收到的数据&#xff0c;以便于我们对数据进行分析。 实现这一想法我们很容易就会想到队列&#xff0c;队列就是一种先进先出的数据结构&#xff0c;之前在《数据结构&#xff1a;基于数组的环形队列&…

最新最全智能科学与技术专业毕业设计选题精华汇总-持续更新中

文章目录 0 简介1 如何选题2 最新智能科学与技术毕设选题3 最后 0 简介 Hi&#xff0c;大家好&#xff0c;随着毕业季的临近&#xff0c;许多同学开始向学长咨询关于选题和开题的问题。在这里&#xff0c;学长分享一些关于智能科学与技术专业毕业设计选题的内容。 以下为学长…

人大金仓大小写敏感处理

人大金仓安装的时候&#xff0c;不管是否选择大小写敏感&#xff1b;查询的时候加和不加双引号&#xff0c;查询出来的都是小写 针对人大金仓大小写&#xff0c;我们实际引用全是大写的情况&#xff0c;解决方案如下 添加配置&#xff0c;将查询结果全都转成大写 1、本地打开…

基于信号分解的几种一维时间序列降噪方法(MATLAB R2021B)

自适应信号分解算法是一种适合对非平稳信号分析的方法&#xff0c;它将一个信号分解为多个模态叠加的形式&#xff0c;进而可以准确反应信号中所包含的频率分量以及瞬时频率随时间变化的规律。自适应信号分解算法与众多“刚性”方法(如傅里叶变换&#xff0c;小波变换)不同&…

SpringBoot3整合mybatis

SpringBoot3整合mybatis 一、添加mybatis的依赖二、通过XML配置三、通过yum或properties文件配置四、常用注解1.Mapper2.MapperScan 一、添加mybatis的依赖 <!--mybatis--> <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>…

简单的网页制作

1网页编写格式 <!DOCTYPE html> <html><head><meta charset"utf-8"> <title>中文测试。。。。</title></head><body>这里是测试body测试内容。。。</body> </html>2标签 在body内<h1></h1&…

鸿蒙开发实现弹幕功能

鸿蒙开发实现弹幕功能如下&#xff1a; 弹幕轮播组件&#xff1a;BannerScroll import type { IDanMuInfoList, IDanMuInfoItem } from ../model/DanMuData //定义组件 Component export default struct BannerScroll {//Watch 用来监视状态数据的变化&#xff0c;包括&#…

Java代码基础算法练习-判断字符串是否为回文-2024.03.16

任务描述&#xff1a; 回文串是指一个正读和反读都一样的字符串&#xff0c;比如“level”或者“noon”等。要求输入 一个字符串&#xff0c;判断此字符串是否为回文。&#xff08;注&#xff1a;设字符串长度小于20&#xff09; 任务要求&#xff1a; package suanfa;import…

Vue:内置组件:KeepAlive(缓存组件实例)

一、作用 <KeepAlive></KeepAlive>能缓存包裹的所有组件&#xff0c;保证组件在切换时维持组件状态。 默认情况下&#xff0c;一个组件实例在被替换掉后会被销毁。这会导致它丢失其中所有已变化的状态——当这个组件再一次被显示时&#xff0c;会创建一个只带有初…

部署一个本地的ChatGPT(Ollama)

一 下载Ollama Ollama下载地址&#xff1a;https://ollama.com/download 下载完后 二 安装运行 双击下载好的OllamaSetup.exe开发 安装Ollama: 安装完成后&#xff0c;多了一个Ollama的菜单如下图 &#xff1a; Ollama安装好默认是配置开机运行&#xff0c;如果没有运行可以在…

MyBatis plus自动生成代码

1.pom文件配置 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version> </dependency> <dependency><groupId>com.baomidou</groupId>…

第五十九回 公孙胜芒砀山降魔 晁天王曾头市中箭-飞桨自然语言处理套件PaddleNLP初探

公孙胜献出八卦阵&#xff0c;宋江用八员大将守阵。项充李衮进入阵里&#xff0c;被抓住了。宋江说久闻大名&#xff0c;来梁山吧。两人说誓当效力到死&#xff0c;希望能先放我们两个回去把樊瑞带来一起。见到樊瑞后把宋江讲义气一说&#xff0c;樊瑞说不可逆天&#xff0c;于…

力扣112、113、101--树

112. 路径总和 题目描述&#xff1a; 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。 判断该树中是否存在 根节点到叶子节点 的路径&#xff0c;这条路径上所有节点值相加等于目标和 targetSum 。 如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c…

轻松搞定找不到vcomp140.dll无法继续执行程序的5种方法

在我们日常使用计算机的过程中&#xff0c;频繁且不可避免地会遭遇到各种类型的错误提示信息&#xff0c;这些错误信息往往会在关键时刻阻碍我们的操作进程。其中&#xff0c;有一个颇为常见的错误提示值得我们关注&#xff0c;那就是“vcomp140.dll丢失”。这个错误提示涉及到…