今天搓了一个简单的博客后端,然后之后准备学spring,今天借助gemini和博客简单了解一下spring里面的概念


优秀的设计都致力于一件事,解耦

开闭原则(OCP Open/Closed principle)

  • 软件实体应该对扩展开放,对修改关闭,简单来讲就是不改变已有的稳定代码,添加新功能

依赖倒置原则(DIP dependence inversion principle)

  • 高层模块不应该依赖低层模块,两者都应该依赖于抽象(接口)。简单说就是:要面向接口编程,不要面向具体实现编程,想象一下电脑,电脑(高层模块)不关心你插进来的是U盘、鼠标还是键盘(低层模块/具体实现)。只要它们都符合USB接口规范,就能正常工作。

spring的8个模块

  • spring Core:核心容器,提供了Ioc和DI,负责管理spring中的bean
  • spring Context:在core的基础上增加更多的功能
  • spring ADP:面向切面编程
  • spring DAO:数据访问对象
  • spring ORM:对象关系映射
  • spring Web MVC
  • spring WebFlux
  • spring Web

Ioc 控制反转

  • 核心思想:将创建和管理对象的控制权交给了spring容器

DI 依赖注入

依赖注入是实现控制反转的具体行动。
场景: 一个 Driver (司机) 类需要一辆 Car (车) 才能工作。
传统方式 (没有DI)
Driver 类需要自己主动去创建它所依赖的 Car 对象。

1
2
3
4
5
6
7
8
public class Driver {
// 司机自己负责 new 一辆车,产生了紧密耦合
private Car car = new Car();

public void drive() {
car.run();
}
}

问题: 这里的 Driver 和 Car 被紧紧地绑定在了一起。如果想让这个司机开卡车,就必须修改 Driver 类的内部代码,这违反了开闭原则。
Spring的方式 (使用DI)
Driver 类不再自己创建 Car,它只是声明“我需要一辆车”。具体的车由外部的 Spring容器 创建,并通过某种方式**“注入”**给 Driver。

最常见的注入方式是构造函数注入:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Driver {
// 司机不再自己new车,而是声明一个依赖
private final Car car;

// 通过构造函数,等待外部把一辆车“注入”进来
public Driver(Car injectedCar) {
this.car = injectedCar;
}

public void drive() {
car.run();
}
}

优势: Driver 类现在只依赖于 Car 这个抽象,而不关心具体的车是如何创建的。Spring容器负责创建 Car 对象,并把它“注入”到 Driver 中。这样,如果想换成卡车,只需修改Spring的配置,Driver 类的代码无需任何改动,完美实现了解耦。

AOP 面向切面编程

  • 核心思想:将横切关注点从业务中分离出来
  • 想象一下你要给一栋大楼里的很多房间(业务方法)都安装监控摄像头(通用功能,如日志)。
    没有AOP: 你需要一个房间一个房间地进去,在墙上打洞,安装摄像头。如果房间很多,会非常麻烦。
    使用AOP: 你设计了一套“中央监控系统”(切面 Aspect)。你只需要定义好“在哪些类型的房间门口安装”(切点 Pointcut)和“具体安装什么”(通知 Advice),系统就会自动完成所有安装工作。这使得你的房间本身保持干净,只关注自己的核心功能。