复习
核心问题:
- Spring 与 两大核心特征(IoC、AOP)
- 控制反转 IoC 依赖注入 DI
- Bean 容器 装配方式
- Bean 的默认作用域和生命周期
- AOP 核心概念(切面/通知/切入点)
- 注解版 AOP 和 五大通知类型
Q&A
Spring 概述:是什么、解决什么问题?
控制反转 IoC 是什么?和 DI 什么关系?
Bean 与容器、装配方式、生命周期?
面向切面编程 AOP 核心概念?
注解版 AOP 五大通知怎么写?
Spring 概述
Spring 是一个开源的轻量级 Java 框架,用于简化企业级应用开发。核心思想是”减少耦合、一切都交给容器管理”。
两大核心特征两大特征就是笔记主题:
- IoC(控制反转) —— 解决”对象之间怎么创建、怎么依赖”的解耦问题。
- AOP(面向切面编程) —— 把日志、事务等横切逻辑从业务代码里抽出来,解决重复代码问题。
一句话:IoC 管”对象和依赖”,AOP 管”公共逻辑抽取”。 两者一起让代码更解耦、更好维护。
Spring 模块/组成(了解层级):
| 模块 | 职责 |
|---|---|
| Core / Bean(核心容器) | IoC 容器、Bean 管理(本讲重点) |
| AOP | 面向切面编程 |
| MVC | Web/HTTP 层的表示层框架 |
| JDBC / 事务 | 数据访问与事务管理 |
| 其他(Security、Boot、Cloud 等) | 安全、快速构建、微服务生态 |
为什么学它写代码最怕”牵一发动全身”:A 要 new B、B 又依赖 C,改一处全崩。Spring 用容器统一创建和管理对象,你的类只需要”声明我要什么依赖”,剩下的容器给。这就是 IoC 的价值。
控制反转 IoC
IoC(Inversion of Control,控制反转):把对象的创建和依赖关系的管理权,从程序员手里”反”交给 Spring 容器。
- 传统方式(正向):谁要用对象,谁自己
new,并自己拼好依赖。 - IoC 方式:对象由容器统一创建,用到时从容器”取”,依赖由容器注入。程序员不再主动 new,所以叫”控制反转”。
依赖注入 DI(Dependency Injection)
实现 IoC 的主要方式(手段) 叫 DI(依赖注入)——容器把依赖”注入”进需要它的对象。IoC 是思想,DI 是做法,两者常混用。
常用注入方式:
| 方式 | 说明 | 典型写法 |
|---|---|---|
| 构造器注入 | 通过构造方法传入依赖 | @Autowired + 构造参数 |
| Setter 注入 | 通过 setter 方法传入 | @Autowired + setter |
| 字段注入(简写) | 直接注解字段 | @Autowired 标注在属性上 |
注意注入方向很重要:依赖注入是容器主动把依赖塞进来,而不是类自己去取。这正好体现”控制反转”——主动权在容器不在类。
Bean 与 Spring 容器
Bean:由 Spring 容器创建、管理并组装起来的对象(其实就是类的实例,只是”管制对象”)。
容器(如 ApplicationContext):负责创建、装配、管理所有 Bean 生命周期的”工厂+仓库”。
Bean 的声明 / 装配方式
- 基于 XML(旧方式):在
applicationContext.xml里配置<bean>。 - 基于注解配置类(现代主流):
@Configuration+@Bean方法声明 Bean。 - 基于组件扫描 + 注解(最常用):在类上加组件注解,容器自动扫描注册。
常用组件注解:
| 注解 | 用途 |
|---|---|
@Component | 通用组件(Bean),可再拆成 Service/Repository/Controller |
@Service | 业务层组件 |
@Repository | 数据访问层(DAO)组件 |
@Controller | 控制层组件(Spring MVC) |
@Autowired | 依赖注入,容器自动注入对应 Bean |
@Qualifier / @Value | 指定用哪个 Bean / 注入基础值 |
Bean 作用域(Scope)
| 作用域 | 说明 |
|---|---|
singleton(默认) | 容器中只创建一个实例,所有注入共享同一个 |
prototype | 每次获取都新建一个实例 |
Bean 生命周期
实例化 → 属性赋值(注入) → 初始化(init) → 使用 → 销毁(destroy)再次强调 IoC 的价值有了容器,业务类不需要自己去 new 依赖,只要声明依赖(@Autowired),容器负责创建和注入。改依赖实现时,只需改一处配置/实现类,调用方代码不用动——这就是解耦。
面向切面编程 AOP
AOP(Aspect-Oriented Programming,面向切面编程):把日志、事务、权限校验等**重复出现、与核心业务无关的公共逻辑(横切关注点)**从业务代码里抽出来,统一管理、按需”织入”到业务方法。
- 痛点:如果每个业务方法里都要写一遍”记日志、开事务、校验”,代码大量重复、难以维护。
- 解决:把这些逻辑抽成”切面”,用声明式的方式切入到指定方法,业务方法里只保留核心逻辑。
打比方业务方法是”汉堡”,日志/事务是”芝士和酱”。AOP 允许你不拆开汉堡,也能在整条汉堡外面统一抹上芝士——切开点的逻辑共用一份,改芝士只需改一处。
核心概念
| 概念 | 含义 |
|---|---|
| 切面(Aspect) | 封装横切逻辑的类(即”那套公共逻辑”) |
| 通知(Advice) | 切面里具体要执行的”动作”(如记日志),分 5 种类型 |
| 切入点(Pointcut) | 精确匹配哪些方法要织入的表达式(切到哪) |
| 连接点(JoinPoint) | 程序执行过程中可被切入的点(如某个方法调用) |
| 目标对象(Target) | 被织入横切逻辑的真正业务对象 |
| 织入(Weaving) | 把切面应用到目标对象、生成代理的过程 |
| 代理(Proxy) | 织入后生成的对象,对外表现像原对象但多出通知逻辑 |
关系一句话:切入点选定”切哪些方法”,通知定义”在这些方法上做什么”,二者组合成切面,最终织入目标对象成为代理。
AOP 的两种实现方式
Spring AOP 可通过注解或 XML 配置。现代开发以注解为主。
注解版写法
- 开启:配置类上加
@EnableAspectJAutoProxy。 - 定义切面类:类上加
@Aspect(还要加@Component才能被容器管理)。 - 写通知 + 切入点,在产品 (proprietary)方法上加对应通知注解:
@Component@Aspectpublic class LogAspect {
@Before("execution(* com.example.service.*.*(..))") public void before() { System.out.println("方法执行前:记录日志"); }}五大通知类型(Advice)
| 通知 | 注解 | 执行时机 |
|---|---|---|
| 前置通知 | @Before | 目标方法执行前 |
| 后置通知 | @AfterReturning | 目标方法正常返回后 |
| 异常通知 | @AfterThrowing | 目标方法抛出异常后 |
| 最终通知 | @After | 目标方法结束后(无论成功/异常,类似 finally) |
| 环绕通知 | @Around | 前后都能控制(最强大,可执行 proceed() 决定是否执行目标方法) |
execution(* 包.类.方法(参数))这种叫切入点表达式,用来匹配要拦截的方法。
注意
@AfterReturning只在成功返回触发,异常不触发;@After则无论结果都触发。@Around必须调用proceed()才会执行目标方法,忘了调用目标方法就不会执行(适合权限校验、性能监控)。
本章小结
- Spring = 轻量级 Java 框架,两大核心:IoC(解耦对象和依赖)与 AOP(抽取公共横切逻辑)。
- IoC:把对象创建和依赖管理交给容器;DI 是实现方式(构造/Set/字段注入)。
- Bean:容器管理的对象,默认
singleton,生命周期”实例化→注入→初始化→使用→销毁”。 - AOP:切面(Aspect)= 通知(Advice)+ 切入点(Pointcut);通知分前/后返回/异常/最终/环绕五种,注解
@Aspect+@Before等 +@EnableAspectJAutoProxy最常用。