一、Spring 框架概述
Spring 是一个基于 J2EE 技术的轻量级 Java Web Service 系统应用框架,旨在提高开发人员的开发效率以及系统的可维护性。
Spring 核心特性
轻量级设计
- 核心 Jar 包体积小巧:
spring-web-5.2.0.RELEASE.jar和spring-core-5.2.0.RELEASE.jar均约为 1.4M - 运行时资源消耗低:只需要少量的操作系统资源(内存和 CPU)便能稳定运行
- 无侵入式设计:应用程序代码不依赖 Spring 特定类,业务对象可以不实现 Spring 特定接口
控制反转(IoC)演进 IoC 将对象的创建和依赖关系的管理从应用程序代码转移到 Spring 容器中,这种转变带来了架构上的根本改进:
graph TB
A[传统开发模式] --> B[程序控制对象创建]
B --> C[紧耦合]
C --> D[难以测试]
E[IoC 模式] --> F[容器控制对象创建]
F --> G[松耦合]
G --> H[易于测试]
A --> E
传统开发模式:
// 传统方式 - 主动创建依赖
public class UserService {
private UserDao userDao = new UserDaoImpl();
public void addUser(User user) {
userDao.save(user);
}
}
IoC 模式:
// IoC 方式 - 被动接收依赖
public class UserService {
private UserDao userDao;
// 通过构造器注入依赖
public UserService(UserDao userDao) {
this.userDao = userDao;
}
public void addUser(User user) {
userDao.save(user);
}
}
二、Spring IoC 原理深度解析
IoC 容器工作原理
Spring IoC 容器通过精细的控制流程来管理 Bean 的完整生命周期:
sequenceDiagram
participant C as 容器启动
participant L as 加载配置
participant P as 解析Bean定义
participant I as 实例化Bean
participant DI as 依赖注入
participant Init as 初始化Bean
participant Ready as Bean就绪
C->>L: 读取配置文件/注解
L->>P: 解析Bean定义信息
P->>I: 调用构造器创建实例
I->>DI: 注入依赖对象
DI->>Init: 执行初始化方法
Init->>Ready: Bean准备就绪
Ready->>Ready: 提供服务
Bean 生命周期完整流程
Bean 的生命周期包含从创建到销毁的完整过程,每个阶段都有特定的回调机制:
graph TB
A[开始] --> B[Bean实例化]
B --> C[属性注入]
C --> D[Aware接口回调]
D --> E[BeanPostProcessor前置处理]
E --> F[初始化方法]
F --> G[BeanPostProcessor后置处理]
G --> H[Bean就绪]
H --> I[业务使用]
I --> J[容器关闭]
J --> K[销毁方法]
K --> L[结束]
F --> F1[@PostConstruct]
F --> F2[afterPropertiesSet]
F --> F3[init-method]
K --> K1[@PreDestroy]
K --> K2[destroy]
K --> K3[destroy-method]
生命周期示例代码:
@Component
public class ExampleBean implements BeanNameAware, InitializingBean, DisposableBean {
public ExampleBean() {
System.out.println("1. 构造器调用 - Bean 实例化");
}
@Autowired
public void setDependency(AnotherBean anotherBean) {
System.out.println("2. 依赖注入");
}
@Override
public void setBeanName(String name) {
System.out.println("3. BeanNameAware.setBeanName() 调用");
}
@PostConstruct
public void postConstruct() {
System.out.println("4. @PostConstruct 方法调用");
}
@Override
public void afterPropertiesSet() {
System.out.println("5. InitializingBean.afterPropertiesSet() 调用");
}
@PreDestroy
public void preDestroy() {
System.out.println("6. @PreDestroy 方法调用");
}
}
循环依赖解决方案
Spring 通过三级缓存机制巧妙解决循环依赖问题:
graph TB
A[获取Bean A] --> B{检查一级缓存}
B -->|存在| C[返回完整Bean]
B -->|不存在| D{检查二级缓存}
D -->|存在| E[返回早期Bean]
D -->|不存在| F{检查三级缓存}
F -->|存在| G[通过ObjectFactory获取早期引用]
G --> H[升级到二级缓存]
H --> I[返回早期引用]
F -->|不存在| J[创建Bean实例]
J --> K[加入三级缓存]
K --> L[属性注入]
L --> M[初始化完成]
M --> N[加入一级缓存]
N --> O[清理二三级缓存]
三级缓存实现:
public class DefaultSingletonBeanRegistry {
// 一级缓存:完整Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二级缓存:早期Bean
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// 三级缓存:ObjectFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
}
循环依赖解决流程示例:
sequenceDiagram
participant A as Bean A
participant C1 as 一级缓存
participant C2 as 二级缓存
participant C3 as 三级缓存
participant B as Bean B
A->>C3: 实例化A,加入三级缓存
A->>B: 需要B,开始创建
B->>C3: 实例化B,加入三级缓存
B->>C3: 获取A的ObjectFactory
C3->>C2: A从三级移到二级缓存
B->>B: 完成B的初始化
B->>C1: B加入一级缓存
A->>A: 获取B完成注入
A->>A: 完成A的初始化
A->>C1: A加入一级缓存
三、Spring AOP 原理详解
AOP 核心概念架构
AOP 通过代理模式实现横切关注点的分离:
graph TB
A[业务组件] --> B[目标对象]
B --> C[AOP代理]
C --> D[客户端]
E[切面] --> F[切入点]
E --> G[通知]
F --> H[连接点匹配]
G --> I[横切逻辑]
C --> E
H --> B
I --> C
通知执行顺序
AOP 通知按照特定顺序执行,环绕通知具有最大的控制权:
sequenceDiagram
participant C as 客户端
participant P as 代理对象
participant A as 环绕通知
participant B as 前置通知
participant T as 目标方法
participant R as 返回通知
participant E as 异常通知
participant F as 后置通知
participant Z as 环绕后处理
C->>P: 方法调用
P->>A: 环绕前置处理
A->>B: 执行前置通知
B->>T: 调用目标方法
T-->>R: 正常返回
T-->>E: 异常返回
R->>F: 执行后置通知
F->>Z: 执行环绕后处理
E->>F: 执行后置通知
F->>Z: 执行环绕后处理
Z->>C: 返回结果/异常
AOP 示例代码:
@Aspect
@Component
public class LoggingAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
System.out.println("开始执行: " + joinPoint.getSignature().getName());
try {
Object result = joinPoint.proceed();
long endTime = System.currentTimeMillis();
System.out.println("执行完成,耗时: " + (endTime - startTime) + "ms");
return result;
} catch (Exception e) {
System.out.println("执行异常");
throw e;
}
}
}
AOP 实现原理
Spring AOP 根据目标对象的特点智能选择代理方式:
graph TB
A[创建AOP代理] --> B{检查配置}
B -->|proxyTargetClass=true| C[使用CGLIB代理]
B -->|optimize=true| C
B -->|默认| D{目标类是否实现接口}
D -->|是| E[使用JDK动态代理]
D -->|否| C
E --> F[生成接口代理]
C --> G[生成子类代理]
JDK 动态代理执行流程:
sequenceDiagram
participant C as Client
participant P as Proxy
participant H as InvocationHandler
participant T as Target
participant I as InterceptorChain
C->>P: method.invoke
P->>H: invoke
H->>I: 获取拦截器链
I->>I: 执行前置通知
I->>T: 调用目标方法
T-->>I: 返回结果
I->>I: 执行后置通知
I-->>H: 返回结果
H-->>P: 返回结果
P-->>C: 返回结果
四、Spring MVC 工作原理
MVC 架构模式
Spring MVC 采用经典的前端控制器模式:
graph TB
A[浏览器] --> B[DispatcherServlet]
B --> C[HandlerMapping]
C --> D[HandlerAdapter]
D --> E[Controller]
E --> F[Service]
F --> G[DAO]
G --> H[数据库]
E --> I[ModelAndView]
I --> J[ViewResolver]
J --> K[View]
K --> A
subgraph Spring MVC
B
C
D
E
J
K
end
subgraph Business Layer
F
end
subgraph Data Access
G
end
Spring MVC 请求处理完整流程
每个 HTTP 请求都经过精心设计的处理管道:
sequenceDiagram
participant C as 客户端
participant DS as DispatcherServlet
participant HM as HandlerMapping
participant HA as HandlerAdapter
participant IC as 拦截器链
participant CT as Controller
participant VS as ViewResolver
participant V as View
C->>DS: HTTP请求
DS->>HM: 查询处理器
HM-->>DS: 返回HandlerExecutionChain
DS->>HA: 获取HandlerAdapter
HA-->>DS: 返回适配器
DS->>IC: 执行preHandle
IC-->>DS: 返回true/false
DS->>HA: 调用处理器
HA->>CT: 执行Controller
CT-->>HA: 返回ModelAndView
HA-->>DS: 返回ModelAndView
DS->>IC: 执行postHandle
DS->>VS: 解析视图
VS-->>DS: 返回View对象
DS->>V: 渲染视图
V-->>DS: 返回响应内容
DS->>IC: 执行afterCompletion
DS->>C: HTTP响应
Controller 示例:
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
User user = userService.getUserById(id);
return ResponseEntity.ok(user);
}
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
User savedUser = userService.saveUser(user);
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
}
}
五、Spring 事务管理
声明式事务工作原理
Spring 事务通过 AOP 代理实现透明的事务管理:
sequenceDiagram
participant C as 客户端
participant P as 事务代理
participant TM as TransactionManager
participant TS as TransactionStatus
participant M as 目标方法
participant D as 数据源
C->>P: 调用业务方法
P->>TM: 创建事务
TM->>D: 获取连接
D-->>TM: 返回连接
TM->>TS: 创建TransactionStatus
TM-->>P: 返回事务状态
P->>M: 执行目标方法
M->>D: 数据库操作
M-->>P: 返回结果
P->>TM: 提交事务
TM->>D: 提交操作
TM-->>P: 提交完成
P-->>C: 返回结果
Note over M,D: 发生异常时
P->>TM: 回滚事务
TM->>D: 回滚操作
事务配置示例:
@Service
@Transactional
public class UserService {
@Autowired
private UserRepository userRepository;
@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.READ_COMMITTED,
rollbackFor = Exception.class
)
public User createUser(User user) {
// 业务逻辑
return userRepository.save(user);
}
}
事务传播机制
Spring 提供了丰富的事务传播行为应对各种业务场景:
graph TB
A[PROPAGATION_REQUIRED] --> A1[当前有事务]
A --> A2[当前无事务]
A1 --> A3[加入当前事务]
A2 --> A4[创建新事务]
B[PROPAGATION_REQUIRES_NEW] --> B1[挂起当前事务]
B1 --> B2[创建新事务]
C[PROPAGATION_NESTED] --> C1[创建保存点]
C1 --> C2[嵌套事务执行]
D[PROPAGATION_SUPPORTS] --> D1[有事务则加入]
D1 --> D2[无事务则非事务运行]
传播行为使用示例:
@Service
public class OrderService {
@Transactional(propagation = Propagation.REQUIRED)
public void placeOrder(Order order) {
// 主业务逻辑
saveOrder(order);
try {
// 独立事务更新库存
inventoryService.updateInventory(order.getItems());
} catch (InventoryException e) {
// 库存异常不影响订单创建
logger.error("库存更新失败", e);
}
}
}
@Service
public class InventoryService {
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void updateInventory(List<OrderItem> items) {
// 在新事务中执行
// 失败不会影响外部事务
}
}
六、MyBatis 核心原理
MyBatis 整体架构
MyBatis 采用分层架构,各司其职:
graph TB
A[接口层] --> B[核心处理层]
B --> C[基础支撑层]
A --> A1[SqlSession]
A --> A2[Mapper接口]
B --> B1[配置解析]
B --> B2[SQL解析]
B --> B3[SQL执行]
B --> B4[结果映射]
B --> B5[插件拦截]
C --> C1[数据源]
C --> C2[事务管理]
C --> C3[连接池]
C --> C4[缓存]
C --> C5[日志]
B3 --> B31[Executor]
B31 --> B32[StatementHandler]
B32 --> B33[ParameterHandler]
B32 --> B34[ResultSetHandler]
SQL 执行完整流程
从 Mapper 方法调用到数据库操作的完整链路:
sequenceDiagram
participant C as 客户端
participant M as Mapper接口
participant MP as MapperProxy
participant SS as SqlSession
participant E as Executor
participant SH as StatementHandler
participant PH as ParameterHandler
participant RH as ResultSetHandler
participant DB as 数据库
C->>M: 调用Mapper方法
M->>MP: 代理调用
MP->>SS: 获取SqlSession
SS->>E: 执行查询/更新
E->>E: 一级缓存检查
E->>SH: 创建Statement
SH->>PH: 参数处理
PH->>DB: 设置参数
SH->>DB: 执行SQL
DB-->>SH: 返回ResultSet
SH->>RH: 结果集处理
RH-->>SH: 返回Java对象
SH-->>E: 返回结果
E->>E: 缓存结果
E-->>SS: 返回结果
SS-->>MP: 返回结果
MP-->>M: 返回结果
M-->>C: 返回结果
MyBatis 配置和使用示例:
<!-- mapper XML 配置 -->
<mapper namespace="com.example.UserMapper">
<select id="selectUserById" parameterType="long" resultType="User">
SELECT * FROM users WHERE id = #{id}
</select>
</mapper>
// Mapper 接口
public interface UserMapper {
User selectUserById(Long id);
}
// 使用示例
public class UserService {
@Autowired
private UserMapper userMapper;
public User getUser(Long id) {
return userMapper.selectUserById(id);
}
}
MyBatis 缓存机制
MyBatis 的两级缓存机制显著提升性能:
graph TB
A[查询请求] --> B{二级缓存}
B -->|命中| C[返回缓存结果]
B -->|未命中| D{一级缓存}
D -->|命中| E[返回缓存结果]
D -->|未命中| F[数据库查询]
F --> G[结果映射]
G --> H[存入一级缓存]
H --> I[存入二级缓存]
I --> J[返回结果]
K[更新操作] --> L[清空二级缓存]
L --> M[清空一级缓存]
M --> N[执行数据库更新]
subgraph "SqlSession A"
D
H
M
end
subgraph "SqlSession B"
O[一级缓存]
P[清空缓存]
end
subgraph "应用级别"
B
I
L
end
缓存配置示例:
<!-- 开启二级缓存 -->
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
<!-- 使用缓存 -->
<select id="selectUserById" parameterType="long" resultType="User" useCache="true">
SELECT * FROM users WHERE id = #{id}
</select>
七、设计模式在 Spring 中的应用
Spring 中设计模式的应用架构
Spring 框架大量运用经典设计模式,这些模式共同构建了框架的坚实基础:
graph TB
A[设计模式] --> B[创建型模式]
A --> C[结构型模式]
A --> D[行为型模式]
B --> B1[工厂模式]
B1 --> B11[BeanFactory]
B1 --> B12[ApplicationContext]
B --> B2[单例模式]
B2 --> B21[Singleton Bean]
B2 --> B22[单例注册表]
B --> B3[建造者模式]
B3 --> B31[BeanDefinitionBuilder]
C --> C1[代理模式]
C1 --> C11[AOP 代理]
C1 --> C12[事务代理]
C --> C2[适配器模式]
C2 --> C21[HandlerAdapter]
C2 --> C22[AdvisorAdapter]
D --> D1[模板方法模式]
D1 --> D11[JdbcTemplate]
D1 --> D12[TransactionTemplate]
D --> D2[策略模式]
D2 --> D21[资源访问策略]
模板方法模式在 JdbcTemplate 中的应用
JdbcTemplate 是模板方法模式的经典实现:
sequenceDiagram
participant C as 客户端
participant JT as JdbcTemplate
participant CC as ConnectionCallback
participant PS as PreparedStatement
participant RS as ResultSet
participant DB as 数据库
C->>JT: 执行查询
JT->>DB: 获取连接
DB-->>JT: 返回连接
JT->>PS: 创建PreparedStatement
PS-->>JT: 返回Statement
JT->>CC: 执行自定义逻辑
CC->>PS: 设置参数
PS->>DB: 执行SQL
DB-->>PS: 返回ResultSet
PS-->>CC: 返回ResultSet
CC->>RS: 处理结果集
RS-->>CC: 返回Java对象
CC-->>JT: 返回结果
JT->>DB: 释放连接
JT-->>C: 返回结果
JdbcTemplate 使用示例:
@Repository
public class UserRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
public User findById(Long id) {
return jdbcTemplate.queryForObject(
"SELECT * FROM users WHERE id = ?",
new Object[]{id},
(rs, rowNum) -> {
User user = new User();
user.setId(rs.getLong("id"));
user.setName(rs.getString("name"));
user.setEmail(rs.getString("email"));
return user;
}
);
}
}
总结
技术架构演进关系
Spring 和 MyBatis 在整个 Java 技术栈中扮演着重要角色:
graph TB
A[Spring Framework] --> B[核心容器]
A --> C[数据访问]
A --> D[Web 开发]
A --> E[AOP 支持]
A --> F[测试支持]
B --> B1[IoC 容器]
B --> B2[资源管理]
B --> B3[国际化]
B --> B4[事件机制]
C --> C1[事务管理]
C --> C2[DAO 支持]
C --> C3[JDBC 支持]
C --> C4[ORM 集成]
D --> D1[MVC 框架]
D --> D2[Web Socket]
D --> D3[Web Flux]
G[MyBatis] --> H[SQL 映射]
G --> I[缓存机制]
G --> J[插件扩展]
C4 --> G
学习路径建议
掌握 Spring 和 MyBatis 需要系统性的学习路径:
graph TB
A[学习路径] --> B[基础阶段]
A --> C[进阶阶段]
A --> D[精通阶段]
A --> E[专家阶段]
B --> B1[配置使用]
B --> B2[核心概念]
B --> B3[简单应用]
C --> C1[原理理解]
C --> C2[高级特性]
C --> C3[性能优化]
D --> D1[源码分析]
D --> D2[设计思想]
D --> D3[扩展开发]
E --> E1[架构设计]
E --> E2[疑难解决]
E --> E3[最佳实践]
B --> C
C --> D
D --> E
核心价值与未来展望
Spring 框架核心价值:
- IoC 容器:通过控制反转和依赖注入实现松耦合架构
- AOP 编程:通过横切关注点分离提高代码模块化
- 事务管理:提供声明式事务管理保证数据一致性
- MVC 模式:清晰的 Web 开发架构支持复杂应用开发
MyBatis 核心优势:
- SQL 灵活性:SQL 与代码分离,便于优化和维护
- 结果映射:强大的对象关系映射能力
- 缓存机制:两级缓存显著提升性能
- 扩展性:插件机制支持功能定制
实践建议:
- 深入理解原理而非仅仅记忆配置
- 结合实际业务场景选择合适的技术方案
- 关注性能优化和最佳实践
- 持续学习新技术和架构演进
未来发展趋势:
- Spring 向云原生和响应式编程发展
- MyBatis 持续优化性能和扩展能力
- 微服务架构下的技术整合
- 与新技术栈的融合创新
通过本文的全面解析,我们不仅深入理解了 Spring 和 MyBatis 的核心原理,还掌握了它们在实际项目中的应用技巧。这些知识将为您的技术成长和职业发展奠定坚实基础。记住,技术的价值在于解决实际问题,将原理理解与实践经验相结合,才能成为真正的技术专家。