Spring 与 MyBatis 核心原理全面解析

3 阅读5分钟

一、Spring 框架概述

Spring 是一个基于 J2EE 技术的轻量级 Java Web Service 系统应用框架,旨在提高开发人员的开发效率以及系统的可维护性。

Spring 核心特性

轻量级设计

  • 核心 Jar 包体积小巧:spring-web-5.2.0.RELEASE.jarspring-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 框架核心价值

  1. IoC 容器:通过控制反转和依赖注入实现松耦合架构
  2. AOP 编程:通过横切关注点分离提高代码模块化
  3. 事务管理:提供声明式事务管理保证数据一致性
  4. MVC 模式:清晰的 Web 开发架构支持复杂应用开发

MyBatis 核心优势

  1. SQL 灵活性:SQL 与代码分离,便于优化和维护
  2. 结果映射:强大的对象关系映射能力
  3. 缓存机制:两级缓存显著提升性能
  4. 扩展性:插件机制支持功能定制

实践建议

  • 深入理解原理而非仅仅记忆配置
  • 结合实际业务场景选择合适的技术方案
  • 关注性能优化和最佳实践
  • 持续学习新技术和架构演进

未来发展趋势

  • Spring 向云原生和响应式编程发展
  • MyBatis 持续优化性能和扩展能力
  • 微服务架构下的技术整合
  • 与新技术栈的融合创新

通过本文的全面解析,我们不仅深入理解了 Spring 和 MyBatis 的核心原理,还掌握了它们在实际项目中的应用技巧。这些知识将为您的技术成长和职业发展奠定坚实基础。记住,技术的价值在于解决实际问题,将原理理解与实践经验相结合,才能成为真正的技术专家。