深入浅出 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.hqwc.cn/news/544598.html

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

相关文章

如何保存缓存和MySQL的双写一致呢?

如何保存缓存和MySQL的双写一致呢&#xff1f; 所谓的双写一致指的是&#xff0c;在同时使用缓存(如Redis)和数据库(如MySQL)的场景下,确保数据在缓存和数据库中的更新操作保持一致。当对数据进行修改的时候&#xff0c;无论是先修改缓存还是先修改数据库&#xff0c;最终都要保…

Flink 集群部署模式

文章目录 前言一、会话模式&#xff08;Session Mode&#xff09;二、单作业模式&#xff08;Per-Job Mode&#xff09;三、应用模式&#xff08;Application Mode&#xff09; 前言 Flink支持多种集群部署模式&#xff0c;以满足不同场景和需求。以下是Flink的主要集群部署模…

【数据结构取经之路】希尔排序

目录 引言 思想 动图 过程展开图 gap的取值 时间复杂度 空间复杂度 代码及其解释 引言 希尔排序(Shells Sort)是插入排序的一种又称“缩小增量排序”&#xff08;Diminishing Increment Sort&#xff09;&#xff0c;是直接插入排序算法的一种更高效的改进版本。希尔排…

基于GT911触控IC的电容屏在MSP430上的驱动

背景 最近参加公司一个电池测试仪的项目&#xff0c;负责电容屏驱动开发&#xff0c;电容屏的触控IC是汇顶科技的GT911&#xff0c;电容屏的总线接口是I2C。 因为项目沟通方面的失误&#xff0c;本应接到主控芯片的电容屏&#xff0c;被连到了MSP430这款负责供电管理的MCU&…

三.使用java的API文档

在Java中&#xff0c;API是指“应用程序接口”&#xff08;Application Programming Interface&#xff09;。Java API是Java编程语言中提供的类和接口的集合&#xff0c;用于开发各种类型的应用程序。类比C的STL&#xff08;标准模板库&#xff09;。 通俗理解就当做些封装好…

17.搜索二维矩阵Ⅱ

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,2…

【SQL Server】实验七 数据完整性

1 实验目的 掌握实体完整性、参照完整性和用户自定义完整性约束的创建方法。掌握完整性约束的运行检查机制。掌握参照完整性的级联删除和修改方法。掌握正确设计关系模式完整性约束的方法。 2 实验内容 2.1 掌握实体完整性约束的创建和使用方法 创建表时定义由一个属性组成…

BigDecimal保留两位小数失败问题

文章目录 背景问题解决如何测试代码 背景 测试时发现在线swagger测试会自动处理BigDecimal小数点后面的数字&#xff0c;就是有零的会都给你去掉&#xff0c;比如9.000与9.500到最后都会被swagger处理成9跟9.5。使用postman测是最准的&#xff0c;测出来的就是9.000跟9.500。 …

pytorch 入门基础知识一(Pytorch 01)

一 深度学习基础相关 深度学习三个主要的方向&#xff1a;计算机视觉&#xff0c;自然语言&#xff0c;语音识别。 机器学习核心组件&#xff1a;1 数据集(data)&#xff0c;2 前向传播的model(net)&#xff0c;3 目标函数(loss)&#xff0c; 4 调整模型参数和优化函数的算法…

Vue3+TypeScript 学习回顾,温故而知新

文章简介&#xff1a; &#xff08;1&#xff09;简介&#xff1a; 在 Vue3 中编码规范如下&#xff1a; 编码语言: JavaScript代码风格: 组合式API选项式、API简写形式: setup语法糖 &#xff08;2&#xff09;复习内容&#xff1a; 1.核心: ref、reactive、computed、w…

阿里EMO模型:AI生成表情丰富的视频

引言 在数字多媒体的时代&#xff0c;人们对于互动性和个性化视频内容的需求不断增长。阿里巴巴的EMO&#xff08;Emote Portrait Alive&#xff09;模型&#xff0c;作为一项前沿的人工智能技术&#xff0c;正引领着这一领域的革新之路。 EMO模型概述 EMO模型是阿里巴巴智能计…

​​SQLiteC/C++接口详细介绍之sqlite3类(十)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;九&#xff09; 下一篇&#xff1a;​​SQLiteC/C接口详细介绍之sqlite3类&#xff08;十一&#xff09; 30.sqlite3_enable_load_extension&#x…