Java 中的 IoC、AOP、MVC

9 阅读4分钟

Java 中的 IoC、AOP、MVC

这三者是 Java 企业级开发中的核心设计思想和架构模式,经常在 Spring 框架中一起使用。


一、IoC — 控制反转

是什么?

控制反转(Inversion of Control)是一种设计原则:将对象的创建和依赖关系的管理交给容器,而不是由对象自己控制。

传统方式 vs IoC 方式

// ❌ 传统方式:对象自己创建依赖
public class UserService {
    // 自己 new 依赖
    private UserDao userDao = new UserDao();  
    private EmailUtil emailUtil = new EmailUtil();
}

// ✅ IoC 方式:由容器注入依赖
public class UserService {
    @Autowired  // Spring 自动注入
    private UserDao userDao;
    
    @Autowired
    private EmailUtil emailUtil;
}

核心作用

作用说明
解耦类之间不再硬编码依赖,降低耦合度
可测试性方便用 Mock 对象替换真实依赖进行单元测试
统一管理对象的创建、销毁、作用域由容器统一管理
配置灵活通过配置切换实现(如切换数据库实现类)

相关概念

  • DI(依赖注入):IoC 的实现方式,通过构造器、Setter 或注解注入依赖
  • 容器:Spring Container 负责管理 Bean 的生命周期

二、AOP — 面向切面编程

是什么?

面向切面编程(Aspect-Oriented Programming)是一种编程范式,将横切关注点(如日志、事务、权限)从业务逻辑中抽离出来,统一处理。

典型场景

// ❌ 传统方式:业务代码混杂了横切逻辑
public void transferMoney() {
    logger.info("开始转账");           // 日志
    startTransaction();                // 事务
    
    // 核心业务逻辑
    accountService.transfer();
    
    commitTransaction();               // 事务
    logger.info("转账结束");           // 日志
}

// ✅ AOP 方式:业务逻辑保持纯净
@Transactional  // AOP 自动处理事务
public void transferMoney() {
    // 只关心核心业务逻辑
    accountService.transfer();
}

核心概念

术语说明
切面(Aspect)横切关注点的模块化,如 LogAspectTransactionAspect
通知(Advice)具体要执行的增强代码(前置、后置、环绕、异常、最终)
切入点(Pointcut)匹配连接点的表达式,如 execution(* com..*.*(..))
连接点(JoinPoint)程序执行过程中的一个点,如方法调用、异常抛出
织入(Weaving)将切面应用到目标对象的过程

常见应用场景

场景作用
日志记录统一记录方法入参、返回值、执行时间
事务管理声明式事务 @Transactional
权限校验@PreAuthorize 统一鉴权
性能监控统计方法执行耗时
缓存管理@Cacheable 统一缓存处理
异常处理统一捕获并封装异常

三、MVC — 模型-视图-控制器

是什么?

MVC 是一种架构模式,将应用程序分成三个核心组件,实现关注点分离

三层结构

用户请求
   ↓
┌─────────────────────────────────────────┐
│         Controller(控制器)             │
│  - 接收请求,解析参数                    │
│  - 调用业务逻辑                          │
│  - 返回视图或数据                        │
└─────────────────────────────────────────┘
   ↓ 调用
┌─────────────────────────────────────────┐
│           Model(模型)                  │
│  - 业务逻辑(Service)                   │
│  - 数据访问(DAO/Repository)            │
│  - 实体类(Entity)                      │
└─────────────────────────────────────────┘
   ↓ 返回数据
┌─────────────────────────────────────────┐
│           View(视图)                   │
│  - JSP / Thymeleaf / Vue / React        │
│  - 展示数据给用户                        │
└─────────────────────────────────────────┘

Spring MVC 示例

// Controller - 接收请求
@RestController
@RequestMapping("/user")
public class UserController {
    
    @Autowired
    private UserService userService;  // Model
    
    @GetMapping("/{id}")
    public Result getUser(@PathVariable Long id) {
        // 1. 接收请求参数
        // 2. 调用业务逻辑
        User user = userService.getById(id);
        // 3. 返回数据(View 交给前端渲染)
        return Result.success(user);
    }
}

// Model - 业务逻辑 + 数据访问
@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    
    public User getById(Long id) {
        return userMapper.selectById(id);  // 数据访问
    }
}

MVC 核心作用

组件职责作用
Controller请求分发、参数绑定、视图跳转接收用户输入,协调 Model 和 View
Model业务逻辑、数据访问、状态维护封装数据和业务规则
View数据展示、用户交互将数据显示给用户

优点

  • 关注点分离:修改 UI 不影响业务逻辑
  • 可维护性高:各层独立开发、测试
  • 复用性好:同一 Model 可对应多个 View

三者的关系(结合 Spring)

┌─────────────────────────────────────────────────────┐
│                    Spring Framework                  │
├─────────────────────────────────────────────────────┤
│  IoC 容器 ──────→ 管理所有 Bean 的生命周期和依赖     │
│      ↓                                              │
│  AOP 切面 ──────→ 为 Bean 添加横切能力(事务/日志)  │
│      ↓                                              │
│  Spring MVC ─────→ Web 层的请求响应处理              │
└─────────────────────────────────────────────────────┘

典型调用流程

1. 用户发起请求 → Spring MVC 的 DispatcherServlet 接收
2. Controller 处理请求(Controller 由 IoC 容器管理)
3. 调用 Service 层业务逻辑(AOP 事务切面自动开启/提交事务)
4. Service 调用 DAO 层访问数据库
5. 返回数据 → Spring MVC 返回 JSON 或 视图给前端

对比总结

概念类型核心问题典型实现
IoC设计原则"对象谁来创建和管理?"Spring Container
AOP编程范式"横切逻辑如何复用?"Spring AOP、AspectJ
MVC架构模式"Web 层代码如何分层?"Spring MVC、Struts

一句话总结

  • IoC:把对象创建权交给容器,解耦依赖
  • AOP:把通用功能抽成切面,消除重复代码
  • MVC:把 Web 层分成三层,分离关注点