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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 深入浅出 Spring:核心概念和基本用法详解

一、引言

在 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<>();
 
    // 获取所有学生的方法
    @Override
    public List<Student> listAllStudents() {
        return students;
    }
 
    // 获取指定学生的方法
    @Override
    public Student getStudentById(int studentId) {
        return students.stream()
                .filter(student -> student.getId() == studentId)
                .findFirst()
                .orElse(null);
    }
 
    // 创建学生的方法
    @Override
    public void createStudent(Student student) {
        students.add(student);
    }
 
    // 更新学生的方法
    @Override
    public 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("未找到要更新的学生");
                        }
                );
    }
 
    // 删除学生的方法
    @Override
    public 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


相关实践学习
日志服务之数据清洗与入湖
本教程介绍如何使用日志服务接入NGINX模拟数据,通过数据加工对数据进行清洗并归档至OSS中进行存储。
目录
相关文章
|
17天前
|
Java Maven 数据安全/隐私保护
详解 Java AOP:面向方面编程的核心概念与 Spring 实现
详解 Java AOP:面向方面编程的核心概念与 Spring 实现
25 1
|
5天前
|
Java 数据库连接 Spring
Spring底层架构核心概念总结
Spring底层架构核心概念总结
|
4天前
|
消息中间件 Java Maven
深入理解Spring Boot Starter:概念、特点、场景、原理及自定义starter
深入理解Spring Boot Starter:概念、特点、场景、原理及自定义starter
|
4天前
|
前端开发 安全 Java
Spring EL表达式:概念、特性与应用深入解析
Spring EL表达式:概念、特性与应用深入解析
|
17天前
|
前端开发 Java 开发者
深入理解 Spring Boot 注解:核心功能与高级用法详解
深入理解 Spring Boot 注解:核心功能与高级用法详解
24 1
|
20天前
|
JSON Java 数据格式
Spring Boot 中的 @DateTimeFormat 和 @JsonFormat 的用法及作用
【6月更文挑战第11天】在开发 Spring Boot 应用时,处理日期和时间数据是一个常见的需求。Spring Boot 提供了两个注解 @DateTimeFormat 和 @JsonFormat 来帮助我们处理这些问题。
40 4
|
3天前
|
XML 负载均衡 Java
Spring Boot 中实现负载均衡:概念、功能与实现
【6月更文挑战第28天】在分布式系统中,负载均衡(Load Balancing)是指将工作负载和流量分配到多个服务器或服务实例上,以提高系统可用性和响应速度。负载均衡器可以是硬件设备,也可以是软件解决方案。
7 0
|
3天前
|
XML Java 数据库
Spring5系列学习文章分享---第五篇(事务概念+特性+案例+注解声明式事务管理+参数详解 )
Spring5系列学习文章分享---第五篇(事务概念+特性+案例+注解声明式事务管理+参数详解 )
6 0
|
3天前
|
SQL Java 数据库连接
Spring5系列学习文章分享---第四篇(JdbcTemplate+概念配置+增删改查数据+批量操作 )
Spring5系列学习文章分享---第四篇(JdbcTemplate+概念配置+增删改查数据+批量操作 )
6 0
|
3天前
|
XML Java 数据格式
Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))
Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))
7 0