当前位置: 首页 > news >正文

Spring 框架学习指南

Spring 框架是 Java 生态中最主流的企业级应用开发框架,它以 “控制反转(IOC)” 和 “面向切面编程(AOP)” 为核心,提供了一站式的企业级开发解决方案,涵盖依赖管理、事务控制、Web 开发、数据访问等多个领域。本指南将从基础认知到进阶实战,梳理清晰的学习路径,帮助你系统掌握 Spring 框架。

一、Spring 框架基础认知

在深入技术细节前,需先建立对 Spring 框架的宏观理解,明确其核心价值与生态构成。

1. 什么是 Spring?

Spring 是一个开源的轻量级 Java 开发框架,由 Rod Johnson 于 2003 年推出。它的核心目标是 “简化 Java 开发”,通过以下方式实现:

  • 降低组件耦合:基于 IOC 容器管理对象依赖,替代手动创建对象。
  • 增强代码复用:通过 AOP 实现日志、事务等横切关注点的模块化。
  • 整合第三方框架:提供对 MyBatis、Hibernate、Redis 等主流工具的无缝集成。
  • 简化配置:从早期的 XML 配置到注解配置,再到 JavaConfig,逐步降低配置复杂度。

2. Spring 核心优势

  • 轻量级:核心模块体积小,无强制依赖,可按需引入。
  • 非侵入式:使用 Spring 时无需让业务类继承特定父类或实现特定接口(早期部分 API 除外)。
  • 容器化:IOC 容器统一管理对象的生命周期(创建、初始化、销毁)。
  • 面向切面:AOP 支持将日志、安全、事务等通用逻辑与业务逻辑分离。
  • 声明式事务:通过注解或配置即可实现事务控制,无需手动编写事务代码。
  • 生态完善:Spring 生态涵盖 Web(Spring MVC)、微服务(Spring Boot/Spring Cloud)、安全(Spring Security)等全场景。

3. Spring 框架核心模块

Spring 框架由多个功能独立的模块组成,可根据需求选择性引入。核心模块如下:

在这里插入图片描述

二、学习前置知识

Spring 框架基于 Java 技术栈,学习前需掌握以下基础能力,否则会陷入 “看懂代码但不懂原理” 的困境:

  • Java 基础:熟练掌握面向对象(OOP)、注解、反射、泛型、集合框架(List/Map)。
  • Java EE 基础:了解 Servlet、JSP、JDBC 的基本使用(如连接数据库、编写简单 Web 程序)。
  • 设计模式:理解核心设计模式(工厂模式、单例模式、代理模式、观察者模式),这是 IOC/AOP 的原理基础。
  • Maven/Gradle:掌握依赖管理工具的使用,用于引入 Spring 及第三方框架的 Jar 包。

三、核心技术学习路径(从入门到进阶)

Spring 学习的核心是 “先掌握用法,再理解原理”,按 “基础用法 → 核心原理 → 实战应用” 的顺序推进。

阶段 1:Spring IOC 容器(核心基础)

IOC(Inversion of Control,控制反转)是 Spring 框架的灵魂,所有功能都基于 IOC 容器展开。需重点掌握 “容器如何管理对象”“对象依赖如何注入”。

IOC 核心概念:

  • 控制反转:将对象的创建权从 “手动 new” 转移到 Spring 容器,由容器 “主动推送” 对象(而非手动索取),即 “反转了创建对象的控制权”。
  • 依赖注入(DI):IOC 的具体实现方式,容器在创建对象时自动将其依赖的其他对象注入(如通过构造器、setter 方法)。
  • Bean:Spring 容器管理的对象统称为 “Bean”,对应业务中的服务类、DAO 类等。
2. 重点学习内容
  • IOC 容器初始化:
    • 核心容器接口:BeanFactory(基础接口,延迟初始化 Bean)、ApplicationContext(高级接口,继承 BeanFactory,支持即时初始化、国际化等)。
    • 常用 ApplicationContext 实现类:ClassPathXmlApplicationContext(加载类路径下的 XML 配置)、AnnotationConfigApplicationContext(加载注解配置类)。

Bean 的配置方式(3 种主流方式,需全部掌握):

  • XML 配置(早期主流,理解原理):
<!-- 定义 Bean -->
<bean id="userService" class="com.example.service.UserService"><!-- 构造器注入 --><constructor-arg ref="userDao"/><!-- setter 注入 --><property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="com.example.dao.UserDaoImpl"/>
  • 注解配置(当前主流,简化开发):
    • 用 @Component(通用 Bean)、@Service(服务层)、@Repository(DAO 层)、@Controller(Web 层)标注 Bean。
    • 用 @Autowired(按类型注入)、@Qualifier(按名称注入)、@Resource(按名称 / 类型注入,JDK 注解)实现依赖注入。
    • 用 @Configuration 标注配置类,@ComponentScan 开启包扫描。

JavaConfig 配置(纯 Java 代码,类型安全):

@Configuration
@ComponentScan("com.example") // 扫描指定包下的注解 Bean
public class SpringConfig {// 手动定义 Bean@Beanpublic UserDao userDao() {return new UserDaoImpl();}
}

Bean 的核心特性:

  • 作用域:默认 singleton(单例,容器中只有一个实例)、prototype(多例,每次获取创建新实例),还有 request/session(Web 环境专用)。
  • 生命周期:Bean 的创建流程(实例化 → 依赖注入 → 初始化(init-method/@PostConstruct)→ 使用 → 销毁(destroy-method/@PreDestroy))。
  • 延迟加载:对单例 Bean 开启 lazy-init=“true” 或 @Lazy,容器初始化时不创建实例,首次获取时创建。

阶段 2:Spring AOP(核心进阶)

AOP(Aspect-Oriented Programming,面向切面编程)是 Spring 解决 “横切关注点”(如日志、事务、安全)的核心技术,需掌握其概念与实际应用。

1. AOP 核心概念

先理解 AOP 的基础术语,否则难以看懂配置与代码:

  • 切面(Aspect):横切关注点的模块化(如 “日志切面”“事务切面”),通常是一个类。
  • 通知(Advice):切面中的具体逻辑(如日志的 “打印前”“打印后”),分为 5 种类型:
    • @Before:目标方法执行前执行。
    • @AfterReturning:目标方法正常返回后执行。
    • @AfterThrowing:目标方法抛出异常后执行。
    • @After:目标方法执行完成后执行(无论成功 / 异常)。
    • @Around:环绕目标方法,可在执行前后插入逻辑(最灵活)。
  • 连接点(JoinPoint):程序执行过程中的 “可切入位置”(如方法执行、字段赋值),Spring AOP 仅支持 “方法连接点”。
  • 切点(Pointcut):筛选连接点的规则(如 “所有 Service 类的 save 方法”),通过切点表达式定义。
  • 目标对象(Target):被切面增强的原始对象。
  • 代理对象(Proxy):Spring AOP 通过动态代理生成的对象,包含原始对象逻辑 + 切面逻辑。

2. 重点学习内容

AOP 实现方式:

  • JDK 动态代理:基于接口实现,目标对象必须实现接口,Spring 默认优先使用。
  • CGLIB 动态代理:基于子类继承实现,无需接口,目标对象不能是 final 类。
    可通过配置强制使用 CGLIB(Spring Boot 2.x 后默认对接口用 JDK 代理,对类用 CGLIB 代理)。
    基于注解的 AOP 开发(当前主流):

引入依赖(Spring AOP + AspectJ):

<dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.3.20</version>
</dependency>
<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.9.1</version>
</dependency>

编写切面类:

@Component // 纳入 IOC 容器
@Aspect // 标记为切面
public class LogAspect {// 切点表达式:匹配 com.example.service 包下所有类的所有方法@Pointcut("execution(* com.example.service.*.*(..))")public void servicePointcut() {}// 前置通知@Before("servicePointcut()")public void beforeAdvice(JoinPoint joinPoint) {String methodName = joinPoint.getSignature().getName();System.out.println("方法 " + methodName + " 执行前...");}// 环绕通知@Around("servicePointcut()")public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {long start = System.currentTimeMillis();Object result = pjp.proceed(); // 执行目标方法long end = System.currentTimeMillis();System.out.println("方法执行耗时:" + (end - start) + "ms");return result;}
}

在配置类中开启 AOP 注解支持:

@Configuration
@ComponentScan("com.example")
@EnableAspectJAutoProxy // 开启 AspectJ 注解支持
public class SpringConfig {}

切点表达式语法:核心格式:execution(访问修饰符 返回值 包名.类名.方法名(参数类型))

  • 通配符:
    • *:匹配任意字符(如任意返回值、任意方法名)。
    • …:匹配任意层级的包或任意个数的参数。
  • 示例:
    • execution(* com.example.service..(…)):匹配 service 包下所有类的所有方法。
    • execution(public * com.example.service.UserService.save(…)):匹配 UserService 的 public save 方法。

阶段 3:Spring 事务管理(实战核心)

事务是保证数据一致性的关键,Spring 提供的 “声明式事务” 极大简化了事务开发,是企业级应用的必备技能。

1. 事务基础概念

  • ACID 特性:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
  • 事务隔离级别:解决并发事务问题(脏读、不可重复读、幻读),Spring 支持 5 种级别:
    • DEFAULT:默认,使用数据库的隔离级别(如 MySQL 默认为 REPEATABLE_READ)。
    • READ_UNCOMMITTED:读未提交(最低级别,允许脏读)。
    • READ_COMMITTED:读已提交(避免脏读)。
    • REPEATABLE_READ:可重复读(避免脏读、不可重复读)。
    • SERIALIZABLE:串行化(最高级别,避免所有并发问题,但性能差)。
  • 事务传播行为:多个事务方法嵌套时,事务的传递规则(核心重点),常用传播行为:
    • REQUIRED(默认):如果当前有事务,加入事务;无事务则创建新事务。
    • REQUIRES_NEW:无论当前是否有事务,都创建新事务(原事务挂起)。
    • SUPPORTS:如果当前有事务,加入事务;无事务则以非事务方式执行。
    • NOT_SUPPORTED:以非事务方式执行,若当前有事务则挂起。
    • NEVER:以非事务方式执行,若当前有事务则抛出异常。

2. 重点学习内容

声明式事务实现(基于注解):

配置事务管理器(以 JDBC 为例):


```java
@Configuration
@ComponentScan("com.example")
@EnableTransactionManagement // 开启声明式事务支持
public class SpringConfig {// 数据源(简化示例,实际需配置数据库连接信息)@Beanpublic DataSource dataSource() {DriverManagerDataSource ds = new DriverManagerDataSource();ds.setDriverClassName("com.mysql.cj.jdbc.Driver");ds.setUrl("jdbc:mysql://localhost:3306/test");ds.setUsername("root");ds.setPassword("123456");return ds;}// JDBC 模板@Beanpublic JdbcTemplate jdbcTemplate(DataSource dataSource) {return new JdbcTemplate(dataSource);}// 事务管理器@Beanpublic PlatformTransactionManager transactionManager(DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
}

在业务方法上添加 @Transactional 注解:

@Service
public class UserService {@Autowiredprivate UserDao userDao;// 声明式事务:默认隔离级别,传播行为 REQUIRED@Transactional(rollbackFor = Exception.class) // 所有异常都回滚(默认仅回滚运行时异常)public void transfer(String from, String to, double money) {userDao.deduct(from, money); // 扣钱// 模拟异常,事务应回滚// int i = 1 / 0;userDao.add(to, money); // 加钱}
}

事务失效的常见原因:

  • 方法不是 public 修饰(@Transactional 仅对 public 方法生效)。
  • 异常类型不匹配(默认仅回滚 RuntimeException,需通过 rollbackFor 指定 checked 异常)。
  • 事务管理器未配置或配置错误。
  • 方法内部调用(如 A 方法调用本类的 B 方法,B 方法的 @Transactional 失效,因未经过代理对象)。

阶段 4:Spring 与第三方框架集成(实战必备)

Spring 本身不实现具体业务功能(如数据访问),而是通过集成第三方框架发挥价值。最常用的集成场景是 Spring + MyBatis(数据访问层)。

1. Spring 集成 MyBatis 核心步骤

引入依赖:

<!-- Spring JDBC -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.3.20</version>
</dependency>
<!-- MyBatis -->
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.11</version>
</dependency>
<!-- MyBatis-Spring 集成包 -->
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.1.7</version>
</dependency>

配置 MyBatis 核心组件(基于 JavaConfig):

@Configuration
@ComponentScan("com.example")
@EnableTransactionManagement
public class SpringMyBatisConfig {// 1. 数据源@Beanpublic DataSource dataSource() {DriverManagerDataSource ds = new DriverManagerDataSource();ds.setDriverClassName("com.mysql.cj.jdbc.Driver");ds.setUrl("jdbc:mysql://localhost:3306/test");ds.setUsername("root");ds.setPassword("123456");return ds;}// 2. SqlSessionFactory(MyBatis 核心)@Beanpublic SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();factoryBean.setDataSource(dataSource);// 配置 MyBatis 映射文件路径factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));// 配置别名包(简化映射文件中的类名)factoryBean.setTypeAliasesPackage("com.example.entity");return factoryBean.getObject();}// 3. Mapper 扫描器(自动生成 Mapper 接口的实现类并纳入 IOC 容器)@Beanpublic MapperScannerConfigurer mapperScannerConfigurer() {MapperScannerConfigurer scanner = new MapperScannerConfigurer();scanner.setBasePackage("com.example.mapper"); // 扫描 Mapper 接口包return scanner;}// 4. 事务管理器@Beanpublic PlatformTransactionManager transactionManager(DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
}

编写 Mapper 接口与映射文件:

  • Mapper 接口:
public interface UserMapper {User selectById(Integer id);void updateBalance(@Param("id") Integer id, @Param("money") double money);
}
  • 映射文件(classpath:mapper/UserMapper.xml):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper"><select id="selectById" resultType="User">select * from user where id = #{id}</select><update id="updateBalance">update user set balance = balance + #{money} where id = #{id}</update>
</mapper>

业务层调用 Mapper:

@Service
public class UserService {@Autowiredprivate UserMapper userMapper;@Transactionalpublic void transfer(Integer fromId, Integer toId, double money) {userMapper.updateBalance(fromId, -money); // 扣钱userMapper.updateBalance(toId, money);    // 加钱}
}

四、进阶与源码学习

掌握基础用法后,若想深入 Spring 框架(如面试或架构设计),需学习源码与进阶特性。

1. 源码核心方向

  • IOC 容器初始化流程:跟踪 ApplicationContext 的创建过程,理解 Bean 的扫描、注册、实例化、依赖注入的底层实现。
  • Bean 的循环依赖解决:Spring 如何通过 “三级缓存” 解决单例 Bean 的循环依赖问题(核心面试题)。
  • AOP 动态代理实现:对比 JDK 动态代理(Proxy 类)与 CGLIB 代理(Enhancer 类)的源码差异。
  • 事务管理器底层:PlatformTransactionManager 的实现原理,声明式事务如何通过 AOP 切入并控制事务。

2. 进阶特性

  • Spring 事件机制:基于观察者模式,实现组件间解耦(ApplicationEvent、ApplicationListener)。
  • Spring 类型转换:自定义类型转换器(Converter 接口),处理特殊类型的注入。
  • Spring EL 表达式:在配置中使用 EL 表达式动态获取值(如 @Value(“${user.name}”))。

五、推荐学习资源

1. 官方文档(权威首选)

Spring Framework 官方文档:涵盖所有模块的详细说明,建议重点阅读 “IoC Container”“AOP”“Transaction Management” 章节。

2. 经典书籍

  • 入门级:《Spring 实战(第 5 版)》:通俗易懂,结合案例讲解核心用法,适合初学者。
  • 进阶级:《Spring 源码深度解析(第 2 版)》:深入源码剖析 IOC、AOP 核心原理,适合进阶。
  • 实战级:《Spring 微服务实战》:结合 Spring Boot/Spring Cloud,讲解 Spring 在微服务中的应用。

3. 视频课程

  • 入门:B 站 “尚硅谷 Spring 框架教程”:从基础到实战,案例详细,适合零基础。
  • 进阶:B 站 “黑马程序员 Spring 源码解析”:针对源码重点(如循环依赖、AOP 代理)进行拆解。

4. 实战项目

基础项目:实现一个 “用户管理系统”,包含 CRUD、事务控制、AOP 日志,整合 Spring + MyBatis。
进阶项目:基于 Spring MVC + Spring + MyBatis(SSM)实现 “电商后台管理系统”,涵盖用户认证、订单管理、权限控制。

六、学习建议与避坑指南

  • 先动手,后原理:不要一开始就啃源码,先通过小案例掌握 IOC/AOP/ 事务的用法,再回头深究原理。
  • 重视依赖管理:Spring 各模块及第三方框架(如 MyBatis)的版本需匹配(如 Spring 5.x 对应 MyBatis 3.5.x),避免版本冲突。
  • 调试源码:通过 IDE(如 IDEA)断点调试 IOC 容器初始化、Bean 创建流程,直观理解底层逻辑。
  • 避坑重点:
    • 事务失效的 5 种常见原因(前文已列)需牢记,实战中优先排查。
    • 注解扫描路径错误:确保 @ComponentScan 覆盖所有业务类包。
    • 循环依赖问题:单例 Bean 可通过三级缓存解决,多例 Bean 循环依赖会抛出异常,需手动处理。
http://www.dtcms.com/a/395877.html

相关文章:

  • Vue3 父子组件通信实战:props 与 provide/inject 方案对比及用法解析
  • el-image标签预览和VForm打包后项目上层级冲突问题
  • QML学习笔记(九)QML的全局对象
  • element里的select自定义输入的时候,不用点击下拉框选中自定义输入,而是当焦点失去的时候自动赋值输入的内容
  • 链改2.0+港促会,携手赋能 Web3引企赴港!
  • C++第二篇:命名空间(namespace)
  • vcsa 重启服务
  • QT 两种库写法 LIBS += .a和LIBS += -L -l
  • 比斯特自动化|电动自行车电池点焊机的作用与使用
  • Django 模型与 ORM 全解析(一):从基础到实战的完整指南
  • NW955NW960美光固态闪存NW963NW971
  • iOS 26 软件兼容性大检查,哪些 App 出问题、API 变动要注意、旧功能不支持兼容性测试全流程
  • HarmonyOS NEXT互动卡片开发:从原理到实战的完整指南
  • 邪修实战系列(6)
  • Clover: 1靶场渗透
  • 智慧供水管网监测解决方案:实现压力、流量、水质数据集与监控
  • 深入理解Java虚拟机内存模型
  • 什么是缺陷检测?机器视觉表面缺陷检测从定义到实战方法,避开漏判误判
  • Svelte:编译时优化原理、与传统虚拟DOM框架的性能对比性能优化
  • 属性描述符
  • JavaWeb之JSP 快递管理与过滤器详解
  • 《MedChat智能医疗问答系统》项目介绍
  • 使用FastAPI和Docker部署机器学习模型:从开发到生产的最佳实践
  • Per-Tensor 量化和Per-Channel 量化
  • 执行bat任务栏有图标显示,执行pycharm64.exe就没有是什么原因
  • 【Docker项目实战】使用Docker部署wealth-tracker个人资产分析工具
  • LeapMotion_Demo演示
  • 智慧图书管理|基于SprinBoot+vue的智慧图书管理系统(源码+数据库+文档)
  • 面试技巧第四篇:嵌入式通信机制考点:消息队列、信号量与互斥锁
  • 面试八股:C语言的预处理和类型定义