Spring与SpringBoot

Spring是一个开源的企业级Java应用程序框架,由Rod Johnson于2002年创立,2003年正式发布第一个版本,其核心目标是"简化Java开发",解决传统Java EE开发的复杂性、耦合度高、配置繁琐等问题。经过二十余年的发展,Spring已从最初的基础框架,发展为一个庞大的生态体系,涵盖Web开发、数据访问、安全、测试等各个领域,成为Java企业级开发的"事实标准"------几乎所有Java后端项目,都会基于Spring框架搭建。

很多开发者会把Spring和Spring Boot混淆,其实Spring是核心基础,Spring Boot是基于Spring的"简化开发工具"(后续会详细区分)。本文将从核心思想、架构组成、核心功能、常用注解、实战要点等方面,彻底讲懂Spring框架,帮你从"知其然"到"知其所以然"。

一、Spring的核心定位与设计理念

1. 核心定位

Spring不是一个单一功能的框架,而是一个"一站式"的企业级开发框架------它不替代任何现有技术(如JDBC、MyBatis、Servlet),而是通过整合、封装这些技术,提供统一的开发规范和便捷的工具,降低开发难度、提升开发效率,同时实现代码的解耦、可维护性和可扩展性。

Spring的核心价值:简化开发、解耦组件、提供标准化的开发模式,让开发者可以专注于业务逻辑,而非底层基础设施的搭建和配置。

2. 核心设计理念

Spring框架的所有功能,都围绕两大核心思想展开,这也是理解Spring的关键,二者相辅相成、缺一不可:

(1)控制反转(IoC:Inverse of Control)

这是Spring最核心的思想,也是Spring框架的基石。我们先通过"传统开发"与"Spring开发"的对比,理解IoC的本质:

  • 传统开发:开发者手动创建对象、管理对象的依赖关系(比如Service层需要Dao层对象,就手动new一个Dao对象),对象的创建权、依赖管理权完全由开发者控制,导致代码耦合度极高------一旦Dao层代码修改,Service层也需要随之修改,维护成本高。

  • Spring开发:开发者不再手动创建对象,而是将对象的创建、依赖管理交给Spring的"容器"(IoC容器)负责,开发者只需要定义对象的配置信息,由容器统一实例化对象、注入依赖。这种"将控制权从开发者转移到容器"的模式,就是控制反转。

IoC的核心作用:解耦------将对象之间的依赖关系从"硬编码"转为"配置声明",降低组件间的耦合度,提升代码的可维护性和可扩展性。

补充:IoC的具体实现方式是"依赖注入(DI:Dependency Injection)",即容器在创建对象时,自动将其依赖的其他对象注入到当前对象中,无需开发者手动操作。依赖注入的常见方式有3种:构造器注入、Setter方法注入、注解注入(@Autowired,最常用)。

(2)面向切面编程(AOP:Aspect Oriented Programming)

AOP是Spring的另一大核心思想,用于解决"横切关注点"的统一处理问题。所谓"横切关注点",是指那些横跨多个组件、无法通过传统OOP(面向对象)封装的通用逻辑,比如日志记录、权限校验、事务管理、异常处理等------这些逻辑如果写在每个业务组件中,会导致代码冗余、难以维护。

AOP的核心思想:将横切关注点与业务逻辑分离,通过"动态代理"技术,将横切逻辑(如日志)织入到业务逻辑中,实现"一次编写、处处可用",既减少代码冗余,又便于统一维护。

举个例子:所有Service层的方法都需要记录"方法调用日志",如果没有AOP,就需要在每个Service方法中都写日志代码;有了AOP,只需编写一个日志切面,定义好需要拦截的方法,就能自动为所有匹配的方法添加日志逻辑,无需修改业务代码。

Spring AOP的核心术语(必懂):

  • 切面(Aspect):封装横切逻辑的类(如日志切面、事务切面),通过@Aspect注解标识。

  • 连接点(Join Point):程序执行过程中的某个节点(如方法执行、异常抛出),Spring AOP中主要指方法执行。

  • 切入点(Pointcut):匹配连接点的规则(如"所有Service层的方法"),通过切入点表达式定义。

  • 通知(Advice):切面在连接点执行的具体逻辑,分为前置通知(@Before,方法执行前)、后置通知(@After,方法执行后)、环绕通知(@Around,方法执行前后)等。

  • 织入(Weaving):将切面逻辑与业务逻辑结合的过程,Spring AOP在运行时通过动态代理完成织入。

二、Spring的核心架构与模块组成

Spring框架采用"模块化设计",将核心功能拆分为多个独立模块,开发者可以根据需求按需引入,无需引入整个框架,既降低了项目体积,又提升了灵活性。Spring的核心模块主要分为5大类,各模块相互独立又相互依赖,构成完整的架构体系:

1. 核心容器模块(Core Container)------ IoC容器的核心

核心容器是Spring的基础,负责对象的创建、配置、依赖注入和生命周期管理,是所有其他模块的基础。主要包含4个模块:

  • spring-core:提供Spring框架的核心基础功能,如IoC容器的核心实现、依赖注入的核心逻辑、Bean的基础管理等。

  • spring-beans:负责Bean的定义、注册、获取和管理,提供BeanFactory接口(IoC容器的基础接口),定义了Bean的生命周期规范。

  • spring-context:扩展了BeanFactory,提供更强大的企业级功能,如国际化支持、事件发布、资源访问、上下文管理等,核心接口是ApplicationContext(实际开发中最常用的IoC容器)。

  • spring-expression:提供Spring表达式语言(SpEL),支持通过表达式动态获取、操作Bean的属性和方法,简化配置。

补充:IoC容器的核心接口体系分为两级:

  • BeanFactory:基础容器接口,提供Bean的注册、获取等最基本功能,延迟加载(仅在调用getBean时创建Bean),轻量级。

  • ApplicationContext:继承自BeanFactory,提供更全面的企业级功能(如国际化、事件发布),预加载单例Bean(启动时创建所有单例Bean),是生产环境的首选。

2. AOP模块(Aspect Oriented Programming)

负责实现AOP功能,提供动态代理、切面织入等核心能力,主要包含2个模块:

  • spring-aop:提供AOP的核心实现,包括动态代理(JDK动态代理、CGLIB代理)、切面、通知、切入点等核心组件。

  • spring-aspects:集成了AspectJ框架(Java领域最成熟的AOP框架),提供更强大的切入点表达式和切面功能,简化AOP开发。

3. 数据访问与集成模块(Data Access/Integration)

负责整合数据访问相关技术,简化数据库操作、事务管理等功能,主要包含5个模块:

  • spring-jdbc:对JDBC进行封装,提供JdbcTemplate工具类,简化JDBC操作(无需手动处理连接、Statement、异常关闭等),提升数据库操作效率。

  • spring-tx:提供事务管理功能,支持声明式事务(通过@Transactional注解,最常用)和编程式事务,无需手动编写事务提交、回滚代码,保证数据一致性。

  • spring-orm:整合主流ORM框架(如MyBatis、Hibernate、JPA),提供统一的操作接口,简化ORM框架的使用。

  • spring-oxm:提供对象与XML之间的转换功能,支持JAXB、Castor等XML解析框架。

  • spring-jms:整合JMS(Java消息服务),支持消息队列(如ActiveMQ),实现异步通信。

4. Web模块(Web)

负责Web应用开发,提供Web层的核心功能,是Spring MVC的基础,主要包含4个模块:

  • spring-web:提供Web应用的基础支持,如Servlet集成、文件上传、Web资源访问等。

  • spring-webmvc:即Spring MVC,Spring的Web层核心框架,基于MVC设计模式,负责请求分发、参数绑定、视图解析等,是Java Web开发的主流框架(前文已详细讲解)。

  • spring-websocket:支持WebSocket协议,实现客户端与服务器的全双工通信(如实时聊天、消息推送)。

  • spring-webflux:提供响应式Web开发支持,基于Reactor框架,适用于高并发、低延迟的Web场景。

5. 其他辅助模块

  • spring-test:提供Spring应用的测试支持,整合JUnit、TestNG等测试框架,支持Mock对象、事务回滚等功能,简化单元测试和集成测试。

  • spring-security:提供安全框架支持,实现认证(登录)、授权(权限控制)、CSRF防护等功能,是Spring生态中常用的安全组件。

  • spring-messaging:提供消息通信支持,统一处理STOMP、WebSocket等消息格式,实现发布-订阅模式的消息传递。

三、Spring的核心功能(实战必懂)

结合日常开发场景,Spring的核心功能主要有6个,也是我们开发中最常用的功能,掌握这些功能,就能应对大部分Java后端开发场景:

1. IoC容器与Bean管理

这是Spring最基础的功能,IoC容器负责管理Bean的全生命周期:从Bean的定义、实例化、依赖注入,到Bean的销毁,全程由容器自动完成,开发者只需通过配置(注解或XML)声明Bean即可。

Bean的核心特性:

  • 作用域:默认是"单例(singleton)"------容器中只存在一个Bean实例,全局共享;其他作用域还有原型(prototype,每次获取都创建新实例)、请求(request,Web场景,每次请求创建一个实例)、会话(session,Web场景,每个会话创建一个实例)等。

  • 生命周期:Bean从创建到销毁的完整流程:Bean定义注册 → 实例化 → 依赖注入 → 初始化(如@PostConstruct注解方法) → 使用 → 销毁(如@PreDestroy注解方法)。

  • Bean的定义方式:3种常用方式------注解定义(@Component及其派生注解,最常用)、XML配置定义、JavaConfig配置(@Configuration + @Bean)。

2. 依赖注入(DI)

依赖注入是IoC的具体实现,Spring支持3种依赖注入方式,日常开发中以注解注入为主:

  • 构造器注入:通过Bean的构造方法注入依赖,适用于"必须依赖"的场景(如Service依赖Dao,没有Dao则Service无法工作),通过@Autowired注解标注构造器。

  • Setter方法注入:通过Bean的Setter方法注入依赖,适用于"可选依赖"的场景,通过@Autowired注解标注Setter方法。

  • 注解注入:直接在依赖字段上标注@Autowired注解,Spring自动注入匹配的Bean,最简洁、最常用。若存在多个相同类型的Bean,可结合@Qualifier注解指定具体Bean。

3. AOP编程

Spring AOP基于动态代理实现,无需修改业务代码,就能实现横切逻辑的统一处理,最常用的场景有:日志记录、权限校验、事务管理、异常统一处理。

Spring AOP的两种实现方式:

  • 注解式AOP:通过@Aspect(标识切面)、@Pointcut(定义切入点)、@Before/@After/@Around(定义通知)等注解,快速实现AOP,是日常开发的首选。

  • XML配置式AOP:通过XML配置文件定义切面、切入点和通知,传统方式,目前已很少使用。

4. 事务管理

Spring提供强大的事务管理功能,无需手动操作事务(提交、回滚),支持"声明式事务"和"编程式事务",其中声明式事务最常用,只需一个@Transactional注解,就能为方法添加事务支持。

声明式事务的核心特点:

  • 简化开发:无需手动编写事务提交、回滚代码,Spring自动管理事务生命周期。

  • 灵活配置:可通过@Transactional注解的属性,配置事务的传播行为(如REQUIRED、SUPPORTS)、隔离级别、超时时间、只读属性等。

  • 全局统一管理:可通过配置,实现全局事务规则,无需在每个方法上重复添加注解。

5. 数据访问整合

Spring通过spring-jdbc、spring-orm等模块,整合JDBC、MyBatis等数据访问技术,简化数据库操作:

  • JdbcTemplate:封装JDBC操作,简化SQL执行、结果映射,避免手动处理连接、异常关闭等繁琐操作。

  • MyBatis整合:通过Spring提供的SqlSessionFactoryBean,整合MyBatis,实现Mapper接口的自动注入,无需手动创建SqlSession。

6. 国际化与资源管理

Spring提供完善的国际化支持,可轻松实现多语言切换(如中文、英文),同时提供统一的资源访问接口(Resource),方便访问类路径、文件系统、URL等各种资源,简化资源管理。

四、Spring常用核心注解(实战高频)

Spring的注解开发是目前的主流,以下是日常开发中最常用、最核心的注解,结合用途和示例说明,记熟这些注解,就能快速上手Spring开发:

1. Bean定义相关注解

  • @Component:通用注解,标注在类上,声明该类是Spring管理的Bean,适用于所有组件(无明确分层)。

  • @Repository:@Component的派生注解,专门标注在数据访问层(Dao层),标识数据访问组件,同时会自动处理数据库相关异常。

  • @Service:@Component的派生注解,专门标注在业务逻辑层(Service层),标识业务处理组件。

  • @Controller:@Component的派生注解,专门标注在Web层(Controller层),标识控制器组件,用于处理HTTP请求(Spring MVC专用)。

  • @Configuration:标注在类上,声明该类是Spring的配置类,替代传统的XML配置文件,类中可通过@Bean注解定义Bean。

  • @Bean:标注在配置类的方法上,方法的返回值会被注册为Spring的Bean,适用于第三方组件的Bean定义(如整合Redis、MyBatis等)。

2. 依赖注入相关注解

  • @Autowired:用于自动注入依赖的Bean,可标注在字段、构造器、Setter方法上,默认按"类型匹配",若有多个同类型Bean,需配合@Qualifier指定Bean名称。

  • @Qualifier:配合@Autowired使用,指定要注入的Bean名称,解决同类型Bean的注入冲突。

  • @Resource:与@Autowired功能类似,用于依赖注入,默认按"名称匹配",若找不到名称,再按类型匹配(JDK原生注解,非Spring注解)。

  • @Value:用于注入外部配置文件(如application.properties)中的属性值,如@Value("${spring.datasource.url}"),可注入字符串、基本类型等。

3. AOP与事务相关注解

  • @Aspect:标注在类上,声明该类是一个切面类,用于封装横切逻辑。

  • @Pointcut:标注在方法上,定义切入点表达式,指定要拦截的方法(如"所有Service层的方法")。

  • @Before:前置通知,标注在切面方法上,在目标方法执行前执行。

  • @After:后置通知,标注在切面方法上,在目标方法执行后执行(无论是否抛出异常)。

  • @Around:环绕通知,标注在切面方法上,包裹目标方法,可在方法执行前后执行逻辑,还能控制方法的执行(如中断方法、修改返回值)。

  • @Transactional:标注在类或方法上,开启声明式事务,Spring自动管理事务的提交、回滚。

4. 其他常用注解

  • @ComponentScan:标注在配置类上,指定Spring扫描Bean的包路径,自动扫描包内带有@Component及其派生注解的类,注册为Bean。

  • @PostConstruct:标注在方法上,该方法会在Bean实例化、依赖注入完成后执行,用于Bean的初始化操作。

  • @PreDestroy:标注在方法上,该方法会在Bean销毁前执行,用于资源清理(如关闭连接、释放资源)。

五、Spring与Spring Boot的区别

很多开发者会混淆Spring和Spring Boot,其实二者并非对立关系,而是"基础与工具"的关系------Spring Boot是基于Spring框架开发的,目的是"简化Spring应用的搭建和开发",核心区别如下:

对比维度 Spring Spring Boot
核心定位 企业级开发框架,提供核心功能(IoC、AOP等),是基础 基于Spring的开发工具,简化Spring应用的搭建和开发
配置方式 需手动配置大量XML或注解(如Bean定义、依赖管理),配置繁琐 遵循"约定优于配置",自动配置核心组件,无需手动配置,仅需少量配置即可启动应用
依赖管理 需手动引入依赖,需关注依赖版本,容易出现版本冲突 提供"起步依赖(Starter Dependencies)",预定义依赖集合,自动管理版本,避免版本冲突
运行方式 需部署到外部Web服务器(如Tomcat),才能运行 内置Tomcat、Jetty等Web服务器,可打包为独立可执行Jar包,直接运行,无需外部服务器
开发效率 较低,需手动搭建项目、配置组件,适合高度定制化场景 极高,零配置快速搭建项目,专注于业务逻辑开发,适合微服务、快速开发场景
关系 Spring Boot的基础,Spring Boot继承了Spring的所有核心功能 Spring的"简化版",不是替代Spring,而是让Spring开发更简单

六、Spring实战要点与常见问题

1. 实战要点

  • Spring的核心是IoC容器,所有Bean都由容器管理,不要手动new容器已管理的Bean,否则无法实现依赖注入和AOP功能。

  • @Transactional注解的生效条件:注解标注在public方法上(非public方法不生效)、Spring容器管理的Bean上(非容器管理的Bean不生效)、未被异常捕获(若异常被手动捕获,事务不会回滚)。

  • Bean的作用域选择:日常开发中,大部分Bean用默认的单例(singleton)即可;若Bean有状态(如包含成员变量且会被修改),需使用原型(prototype)作用域,避免线程安全问题。

  • 依赖注入的优先级:构造器注入 > Setter注入 > 字段注入,推荐使用构造器注入,避免循环依赖问题。

2. 常见问题

  • 循环依赖问题:两个Bean相互依赖(如A依赖B,B依赖A),导致容器无法实例化Bean。解决方案:使用构造器注入改为Setter注入、使用@Lazy注解延迟加载、拆分Bean的依赖关系。

  • @Autowired注入失败:原因可能是Bean未被Spring容器管理(未加@Component等注解)、Bean名称不匹配(需配合@Qualifier)、依赖的Bean未实例化(如延迟加载)。

  • 事务不生效:检查注解是否标注在public方法上、Bean是否被Spring管理、异常是否被手动捕获、事务传播行为是否配置正确。

  • Bean的生命周期方法不执行:检查@PostConstruct、@PreDestroy注解是否正确标注,Bean是否被Spring容器管理,是否使用了正确的容器(如ApplicationContext)。

相关推荐
大傻^1 小时前
Spring AI Alibaba RAG实战:基于向量存储的检索增强生成
java·人工智能·spring
大傻^1 小时前
Spring AI Alibaba 快速入门:基于通义千问的AI应用开发环境搭建
java·人工智能·后端·spring·springai·springaialibaba
心勤则明2 小时前
用 Spring AI Alibaba 打造智能查询增强引擎
java·人工智能·spring
Arva .2 小时前
Spring 的三级缓存,两级够吗
java·spring·缓存
SuniaWang3 小时前
《Spring AI + 大模型全栈实战》学习手册系列 ·专题三:《Embedding 模型选型指南:从 MMTEB 排名到实际应用》
人工智能·学习·spring
进击的野人4 小时前
深入浅出 Spring AI Advisor:自定义你的智能助手拦截器
spring·agent·ai编程
MegaDataFlowers5 小时前
快速上手Spring
java·后端·spring
大傻^5 小时前
Spring AI Alibaba Function Calling:外部工具集成与业务函数注册
java·人工智能·后端·spring·springai·springaialibaba
SuniaWang5 小时前
《Spring AI + 大模型全栈实战》学习手册系列 · 专题四:《Ollama 模型管理与调优:让 AI 模型在低配服务器上流畅运行》
人工智能·学习·spring