Spring Boot 的本质
很多人把Spring Boot想得太过复杂,其实,Spring Boot 的核心底层就是 Spring IOC 容器,你完全可以把这个 IOC 容器,理解成一个 key 为 String 类型、value 为 Object 类型的 Map。
这个Map到底存了什么?
Spring Boot在启动的时候,会自动扫描指定的类,把这些类的实例(也就是我们常说的Bean)全部放进这个Map里。
其中,Map的key就是类名,value就是这个类的单例对象(Spring默认是单例模式)。
那Spring Boot怎么知道,哪些类需要被扫描放进这个Map里?
答案就是注解。
只要类上标注了对应的注解,Spring就会把这个类扫描进容器Map里。
最核心的就是@Component注解,而我们日常用的@Service、@Controller、@Repository(DAO层注解),本质上都是派生自@Component。
所以只要标注了这些注解的类,项目启动时都会被自动扫描进这个大Map里,成为Spring容器管理的Bean。
Spring MVC四层架构
Spring MVC的核心思想就两个字:分层。
说白了,就是把代码按功能拆分成4个模块,对应项目里的4个包,各司其职,互不干扰,既方便维护,也便于团队协作。
1. Entity层(实体层)
它的唯一作用,就是和数据库的表做映射。
数据库里有一张表,Entity层就对应一个类;
数据库里有100张表,这里就有100个对应的类。
类里的属性,就对应数据库表里的字段,就这么简单。
2. DAO层(数据访问层)
无论是手写 SQL 还是框架自动生成 SQL,所有访问数据库的入口定义,都集中在这一层。
3. Service层(业务层)
这是整个项目的核心,所有的业务逻辑都写在这里。
什么是业务逻辑?
举个最经典的银行转账例子:
你要给张三转1000块钱,这个业务的完整流程是:
先校验你的账户余额是否充足➡️余额充足的话给张三的账户加1000元➡️再从你的账户里扣除1000元。
这一整套连贯的业务流程,就写在Service层。
而这个流程里的每一步数据库操作,都是调用DAO层的方法来实现的,Service层本身不写SQL,只负责编排业务逻辑、处理业务规则。
4. Controller层(控制层)
这一层的作用非常纯粹,就是给前端提供可调用的接口,除此之外没有别的核心功能。
正常的Controller层,核心代码往往只有3行:
第一行定义接口地址和请求方式,
第二行调用对应的Service层方法,
第三行把执行结果返回给前端,仅此而已。
依赖注入和控制反转
在讲依赖注入之前,先搞懂控制反转(IOC),它和依赖注入是一体两面的关系,核心逻辑还是离不开那个容器Map。
什么叫“控制反转”?
我们先看“正转”是什么:
如果没有Spring,你想在Controller里用Service,就得自己手动写代码 UserService userService = new UserService();
去创建对象,对象的创建、生命周期、销毁,全都是你自己在代码里控制,这就是“控制正转”。
而有了Spring之后,这件事完全反过来了:
对象的创建、实例化、管理,全都交给Spring容器(也就是那个大Map)来做,你的代码里不用再手动new对象了,只需要等着Spring把你需要的对象给你送过来。
原本由你自己控制的对象管理权,交给了Spring容器,控制权发生了反转,这就是控制反转(IOC)。
而依赖注入(DI),就是Spring实现控制反转最核心的方式。
先看一个最常见的开发场景:
Controller层要调用Service层的方法,那Controller怎么找到Service类的实例?
别忘了,Spring Boot启动的时候,已经把所有标注了注解的类,都放进了那个大Map里。
也就是说,Service的实例早就已经在容器Map里存好了。
那Controller要想用这个Service实例,根本不用自己手动去new对象,只需要通过注解,告诉Spring:
我要这个Service的实例,你给我拿过来。
这个过程,就是依赖注入。
而实现依赖注入,最常用的就是两个注解:
@Autowired 和 @Resource,二选一即可。
你只需要在Controller里,给对应的Service属性加上这个注解,Spring 就会自动从容器 Map 里,按类型或类名找到对应的 Bean 实例,注入到Controller中,你就可以直接调用Service的方法了。