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)。

相关推荐
云烟成雨TD7 小时前
Spring AI 1.x 系列【51】可观测性技术选型
java·人工智能·spring
unicrom_深圳市由你创科技7 小时前
基于Spring AI框架的RAG应用
人工智能·spring·机器学习
七老板的blog9 小时前
当 Spring StateMachine 遇见大模型:构建工业级 AI 写作流水线
java·人工智能·spring
云烟成雨TD9 小时前
Spring AI 1.x 系列【46】MCP Security 模块
java·人工智能·spring
小旭952710 小时前
Spring AI Alibaba 从入门到实战:一站式掌握企业级 AI 应用开发
java·人工智能·spring
云烟成雨TD12 小时前
Spring AI 1.x 系列【50】可观测性:接入 Prometheus + Grafana
人工智能·spring·prometheus
phltxy13 小时前
MCP 从协议到 Spring AI 实战
人工智能·spring·oracle
Volunteer Technology15 小时前
SpringSecurity请求流转的本质
java·spring
云烟成雨TD16 小时前
Spring AI 1.x 系列【42】MCP 服务端 Spring Boot 启动器
java·人工智能·spring
云烟成雨TD17 小时前
Spring AI 1.x 系列【38】模型上下文协议(MCP)
java·人工智能·spring