Spring Core

  • Spring Core(IoC/DI/Bean 生命周期)
    • 概述
      • Spring 的核心是 IoC 容器,它负责把对象 Bean 的创建、依赖装配、生命周期管理、扩展点回调统一托管
      • 写的业务对象只关心需要什么,不关心怎么 new、怎么组装、什么时候初始化/销毁
      • SpringIOC = 依赖反转+容器管理对象生命周期
      • DI = 容器把依赖注入进来(构造器/Setter/字段)
      • Spring 强大来自于:大量可插拔的扩展点(PostProcessor、Aware、Event…)
    • 核心概念与组件
      • Bean、BeanDefinition、Container
        • Bean:被 Spring 容器管理的对象实例
        • BeanDefinition:Bean 的配方/说明书,包括
          • beanClass 类
          • scope (singleton/prototype/…)
          • dependsOn、lazyInit、autowireCandidate…
          • initMethods/destroyMethod
        • 容器(Container)=读取 BeanDefinition->创建 Bean->注入依赖->生命周期回调
      • BeanFactory vs ApplicationContext
        • BeanFactory: 最底层的 IoC 容器接口,延迟实例化为主(按需 getBean 才撞见)
        • ApplicationContext:更企业级,在 BeanFactory 上提供
          • 资源加载
          • 国际化
          • 事件发布(ApplicationEventPublisher)
          • AOP/事务等更完整的生态整合
          • 通常启动时预实例化单例(非 lazy 的 singletone)
    • 装配方式与注入策略
      • 常见装配来源
        • @Component + @ComponentScan:扫描注册
        • @Configuration + @Bean:显式配置注册(配置复杂时使用)
        • @Import:导入配置/Selector/Registrar(Boot 自动配置常用)
        • XML(旧系统常用)
      • 注入方式对比
        • 构造器注入(推荐)
          • 依赖不可变,对象更健壮
          • 便于测试
          • 早失败:缺依赖无法启动
          • 循环依赖无法解决,早暴露设计问题
        • Setter 注入
          • 优点:可选依赖,可后置设置
          • 缺点:对象可能处于半初始化状态
        • 字段注入
          • 难测试
          • 破坏封装
          • 易隐藏循环依赖与设计问题
    • Bean 生命周期全链路
      • 生命周期流程
        • 解析配置 -> 注册 BeanDefinition
        • 实例化:反射/构造器创建对象
        • 属性填充:进行依赖注入
        • Aware 回调
          • BeanNameAware/BeanFactoryAware/ApplicationContextAware 等
        • BeanPostProcessor#postProcessBeforeInitialization
        • 初始化
          • @PostConstructor
          • InitializingBean#afterPropertiesSet
          • 自定义 initMethod
        • BeanPostProcessor#postProcessAfterInitialization
          • AOP 代理通常在这生成(返回代理对象替代原对象)
        • 容器运行期使用
        • 容器关闭,销毁回调
          • @PreDestroy
          • DisposableBean#destroy
          • 自定义 destroyMethod
      • 超级扩展点
        • BeanFactoryPostProcessor(更早、更底层)
          • 作用对象:BeanDefinition
          • 执行时机:Bean 实例化之前
          • 典型用途:
            • 修改 BeanDefinition
            • 解析配置占位符
        • BeanPostProcessor(最常用,最关键)
          • 作用对象:Bean 实例
          • 执行时机:初始化前后(before/after init)
          • 典型用途
            • AOP 代理创建
            • 注解处理,例如 @Autowired 的处理
    • 作用域与懒加载
      • singleton vs prototype
        • singleton:容器内单例,默认
        • prototype:每次 getBean 创建一个新对象,容器只负责创建与注入,不负责销毁
      • @Lazy
        • 对 singleton:延迟到第一次使用才创建
        • 大量 Bean 时可以缩短启动,但是首次请求会变慢
    • 依赖解析与注入规则
      • @Autowired 的匹配策略
        • 先按类型找候选 Bean
        • 如果有多个
          • @Primary 优先
          • @Qualifier(“name”) 指定
          • 再不行:按照字段名/参数名尝试匹配
        • 找不到:默认报错,可以用 required=false 或 Optional 表示可选
      • @Resource vs @Autowired
        • @Resource:默认按 name,再按照 type
        • @Autowired(spring):默认按 type,可以配合 @Qualifier
    • 循环依赖
      • 什么是循环依赖
        • A 依赖 B,B 依赖 A,常在字段/Setter 注入中
      • Spring 为什么能解决部分循环依赖
        • 依赖注入发生在实例化之后
        • 容器允许暴露一个早期引用给对方注入,从而打破死循环
      • 三级缓存
        • 一级缓存:完整初始化好的单例 Bean
        • 二级缓存:早期单例 Bean(半成本引用,可能是原对象,也可能是代理的早期引用)
        • 三级缓存:ObjectFactory(工厂),用于需要时才创建早期引用,并且能让 AOP 有机会在早期阶段接入
      • 典型场景
        • A 依赖 B,B 依赖 A,流程用容器创建 A 为起点
        • 触发创建 A
          • 调用 getBean(“A”)
          • 以及缓存没有 A,进入 createBean(“A”)
        • 实例化 A(还没有注入依赖)
          • Spring 先 instantiate (反射/构造器)得到 A 的空壳对象 A_raw
          • 提前暴露
            • 在进入属性注入之前,Spring 会做循环依赖防护的准备
              • 向三级缓存放入 singletonFactories[“A”] = ObjectFactory
              • 这个 ObjectFactory 的职责是:别人需要 A 的早期引用时,能返回 A_raw 或 A_early_Proxy
            • 此时,A 还没被放入二级缓存,只是放了一个可生产早期引用的工厂到三级缓存
        • 给 A 做属性填充
          • A 需要注入 B -> 容器去 getBean(“B”)
        • 创建 B
          • getBean(“B”) 缓存都没有 -> createBean(“B”)
          • 实例化得到 B_raw
          • 为 B 做提前暴露准备
          • 开始 B 注入依赖
        • B 注入 A(触发早期引用获取)
          • B 需要 A -> 容器调用 getBean(“A”)
          • A 仍然在创建中
          • 一级缓存 singletonObjects:没有
          • 但容器发现 A “currently in creation” 会拿走 getSingleton(“A”, allowEarlyReference=true) 的分支,尝试拿 earlyreference(给 AOP 留入口)
          • 拿到 earlyRef 后,放入二级缓存,移除三级缓存,返回 earlyRef 给 B 注入
        • A 完成初始化,进入一级缓存
          • A 继续完成初始化回调链/BPP afterInitialization
      • 为什么一定要三级
        • 如果只有二级,无法优雅处理什么时候生成代理/早期暴露代理问题
        • 三级缓存工厂,让 Spring 能够在真正需要注入时再决定暴露原对象还是代理对象
      • 哪些循环依赖 Spring 解决不了
        • 构造器注入的循环依赖:实例化阶段就互相需要对方,无法先构造空壳
        • prototype 的循环依赖:每次创建都新对象,不走单例缓存那套
    • @Configuration 为什么特殊(CGLIB 增强)
      • 同一个 @Bean 方法调用两次
        • 普通类写 @Bean 方法,直接调用方法会 new 两次
        • 在 @Configuration 类中,Spring 会用 CGLIB 增强它
          • @Bean 方法被拦截
          • 如果容器里已有该 Bean,就返回容器里的单例,而不是再次执行方法创建

Spring AOP

  • Spring AOP
    • AOP 在 Spring 里解决什么问题
      • 目标:把横切关注点从业务逻辑中剥离出来,日志,鉴权,事务,监控,限流,缓存,重试等
      • Spring AOP 的定位:基于运行时代理,拦截方法调用,织入增强逻辑
      • Spring AOP 只能对方法执行做增强
    • 核心术语与对象模型
      • Join Point/Pointcut/Advice/Aspect
        • JoinPoint:可被拦截的位置。Spring AOP 里基本就是方法执行点。
        • Pointcut:切点表达式,决定哪些 JoinPoint 被拦截。常见:execution/@annotation/within/this/target 等
        • Advice:增强逻辑,要做什么
        • Aspect:切面=Pointcut+Advice 的集合
      • Advisor
        • Advisor:把 Pointcut 和 Advice 打包成一个可应用单元
        • Spring 内部处理的是 Advisor 列表,而不是直接处理注解切面
        • 事务就是一个 Advisor
        • @Aspect 最终会被解析成多个 Advisor,由容器在创建 Bean 时用这些 Advisor 决定是否生成代理以及代理链顺序
    • 代理机制:JDK vs CGLIB
      • JDK 动态代理
        • 只能代理接口
        • 通过 InvocationHandler 拦截接口方法调用
        • 优点:标准 JDK 能力、生成快、类结构简单
        • 缺点:无接口时不可用,对直接调用实现类方法这类场景不覆盖
      • CGLIB 代理
        • 通过生成目标类的子类并覆写方法拦截
        • 适用于无接口的类
        • final 类无法被继承 -> 不能代理
        • final 方法、构造器逻辑、私有方法不能被增强
      • Spring 如何选择代理方式
        • 有接口优先 JDK,没接口用 CGLIB
        • 强制开启 CGLIB @EnableAspectJAutoProxy(proxyTargetClass= true)/spring.aop.proxy-target-class=true
    • Spring AOP 的工作流程
      • Auto Proxy Creator
        • AnnotationAwareAspectJAutoProxyCreator
        • 本质是一个 BeanPostProcessor
        • 介入时机:在 PostProcessAfterInitialization 决定是否为 Bean 创建代理
      • 简化流程
        • 容器启动:扫描到 @Aspect,解析成多个 Advisor
        • 创建普通 BeanX 时
          • AutoProxyCreator 收集可应用到 X 的 Advisor
          • 如果存在匹配
            • 创建代理对象 Proxy(X)
            • 将 Advisor 转成 MethodInterceptor 链
            • 返回 Proxy 替换原对象放入单例池
        • 调用 X.method() 时
          • 进入代理 -> 执行 interceptor chain -> 最后调用目标方法
    • 切点表达式
      • execution
        • execution(访问修饰符 返回类型 包名.类名.方法名(参数))
        • execution(* com.demo.service..*(..)):service 包以及子包所有方法
        • execution(* *..Service.(..)):所有以 Service 结尾类的方法
        • execution(public * *(..)):所有 public 方法
      • 注解切点(工程最常见)
        • @annotation(com.demo.Loggable):方法上标注注解才拦截
        • @within(…):类上注解
        • @target(…):目标对象类型带注解(与代理类型可能有差异
      • within/this/target
        • within(TypePattern):按声明类型匹配
        • this(Type):按代理对象类型匹配
        • target(Type):按目标对象类型匹配
    • Advice 类型与执行顺序
      • 五种 Advice
        • @Before:目标方法前
        • @After:finally(无论是否异常)
        • @AfterReturning:正常返回后
        • @AfterThrowing:抛异常后
        • @Around:最强,包裹整个调用
      • 一个调用的典型顺序
        • Around(进入)
          • Before
            • method 执行
          • AfterReturning/AfterThrowing (二选一)
          • After
        • Around 退出
      • 多个切面怎么排序
        • @Order 数字越小优先级越高(越外层,越先进入 Around)
        • Ordered 接口同理
        • 没有 order:可能按注册顺序
        • 多个 Around 像洋葱圈,order 小的在最外层
      • 代理链/拦截器链
        • Spring 会把 Advisor 适配成一组 MethodInterceptor,形成链
        • MethodInvocation.proceed() 是关键递归点
        • 每个 interceptor 做一段逻辑,然后调用 process() 交给下一个
        • 最后一个调用 invokeJoinPoint() 执行目标方法
    • AOP 经典失效点
      • 自调用失效(No proxy,no AOP)
        • 调用 m1() 内部 m2() 是 this.m2(),不会经过代理 -> @Transactional/@Around 不生效
        • 解决策略
          • 拆分 Bean:把 m2 放到另一个 Spring Bean,通过注入调用
          • 通过 AopContext.currentProxy():获取当前代理再调用,需要 exposeProxy = true,侵入性强
          • 注入自身代理
      • 非 public 方法
      • 直接 new 出来的对象没有 AOP

Spring Transaction

  • Spring Transaction
    • 定义:Spring 事务本质是 AOP 拦截方法调用,在方法执行前后通过 TransactionManager 控制开启/加入事务、提交/回滚、资源绑定/解绑
    • 事务体系的关键对象
      • PlatformTransactionManager:事务管理器抽象
        • DataSourceTransactionManager
        • JpaTransactionManager
      • TransactionDefinition:事务定义(传播、隔离、超时、只读)
      • TransactionStatus:事务状态(是否新建、是否完成、是否回滚标记等)
      • TransactionSynchronzationManager:线程级资源管理
      • Spring 事务是线程绑定资源,所以跨线程(异步)默认不会继承事务上下文
    • @Transactional 做了什么
      • 发生在 AOP 的哪个位置
        • @Transactional 会被解析为一个 Advisor
        • 方法调用进入代理后由 TransactionInterceptor 拦截
        • 会读取事务属性,决定
          • 加入已有事务还是新开事务
          • 方法结束时 commit 还是 rollback
      • 时序
        • 进入代理方法
        • TransactionInterceptor 读取事务属性
        • getTransaction():根据传播行为决定新开/挂起/加入
        • 执行目标方法
        • 正常返回 -> commit()
        • 抛异常 -> 根据回滚规则 rollback() 或者 commit()
    • 传播行为
      • 方法 A 调用方法 B 时,事务边界怎么处理
      • REQUIRED 默认
        • 规则:有事务就加入,没有就新建
        • 典型:大多数业务方法
      • REQUIRES_NEW
        • 规则:总是新建事务,若外部已有事务,则挂起外部事务
        • 典型:记录操作日志/发送消息/保存审计记录
      • NESTED
        • 规则:在外层事务存在时,使用 Savepoint 实现部分回滚
        • 外层回滚:内层也回滚
        • 内层回滚:回到保存点,外层可继续
      • SUPPORTS:有事务就加入,没有就非事务执行
      • NOT_SUPPORTED:总是非事务执行;若有事务则挂起
      • NEVER:如果存在事务则抛异常
      • MANDATORY:必须在事务中运行,否则抛异常
    • 隔离级别
      • Read Uncommitted:可能脏读
      • Read Committed:防脏读
      • Repeatable Read:防不可重复读
      • Serializable:最强,吞吐最差
    • 回滚规则
      • 默认规则
        • 默认只对 RuntimeException 和 Error 回滚
        • 受检异常默认不回滚
      • 配置回滚规则
        • @Transactional(rollbackFor=Exception.class):受检异常也回滚
        • noRollbackFor = XxxException.class:指定异常不回滚
    • 事务提交/回滚的关键机制:线程绑定资源
      • TransactionSynchronizedManager (TSM)
        • 开启事务时
          • 从 DataSource 取 Connection
          • Connection.setAutoCommit(false)
          • 把 Connection 绑定到当前线程(TSM)
        • 同一线程后续 DAO 操作会复用这个 Connection
        • 提交/回滚后
          • commit/rollback
          • 解绑资源,释放连接,恢复 autoCommit 等

Spring MVC

  • SpringMVC(请求链路、参数绑定、异常处理)
    • 总控思维模型
      • Spring MVC 是一个基于 DispatcherServlet 的前端控制器框架,它把一次 HTTP 请求拆分
      • 映射(找谁处理)-> 适配(怎么调用)-> 参数解析(怎么组装入参)-> 执行(调用 controller)-> 返回值处理(怎么写响应)-> 异常处理(失败怎么兜底)
      • 核心入口是 DispatcherServlet#doDispatch:通过 HandlerMapping 找到 handler,再通过 HandlerAdapter 执行;执行前后分别由 ArgumentResolver 和 ReturnValueHandler 处理出参入参,异常交给 HandlerExceptionResolver 链
    • 核心组件和职责
      • DispatcherServlet(总入口)
        • 接受请求
        • 找 Handler(Controller 方法)
        • 调 HandlerAdapter 执行
        • 走视图解析/写回响应
        • 捕获异常并交给异常解析器链
      • HandlerMapping(找谁处理)
        • RequestMappingHandlerMapping:处理 @RequestMapping/@GetMapping,它会维护映射表:URL+HTTP Method+consumers/produces+headers+params->HandlerMethod
      • HandlerAdapter(怎么调用 Handler)
        • RequestMappingHandlerAdapter:负责调用 @RequestMapping 方法
        • 使用 HandlerMethodArgumentResolver 解析方法入参
        • 使用 HandlerMethodReturnValueHandler 处理返回值
      • ViewResolver(视图解析,前后端分离可选)
        • 返回 String 视图名才需要(JSP/Thymeleaf)
        • REST 场景通常直接 @ResponseBody/@RestController,通过 HttpMessageConverter 写响应
      • HttpMessageConverter(对象<->报文)
        • @RequestBody:把 JSON/XML/表单正文 -> Java 对象
        • @ResponseBody:把 Java 对象 -> JSON/XML
        • 常见 Jackson JSON converter
    • 一次请求到完整链路
      • 按 DispatcherServlet#doDispatch 的逻辑
      • 接受请求(Servlet 容器调用 DiapatcherServlet#service)
      • 拿 Handler:遍历 HandlerMapping,找到匹配的 Handler,通常是 HandlerMethod
      • 拿 HandlerAdapter:选择能执行该 Handler 的适配器,通常是 RequestMappingHandlerAdapter
      • 执行前置
        • 绑定/转换:WebDataBinder(类型转换、校验)
        • 参数解析:ArgumentResolver
        • 拦截器 preHandler(HandlerInterceptor)
      • 调用 Controller 方法
      • 处理返回值
        • REST:ReturnValueHandler -> HttpMessageConverter 写回 JSON
        • 视图:返回 ModelAndView -> ViewResolver 渲染
      • 执行后置:拦截器 postHandle/afterCompletion
      • 异常处理:catch 异常 -> HandlerExceptionResolver 链处理->统一响应
    • 请求映射匹配细节
      • @RequestMapping 能参与匹配的额求
        • path(含 Ant 风格、PathVariable)
        • HTTP method (GET/POST/PUT/DELETE)
        • params(必须带参数/参数值)
        • headers (必须带 header)
        • consumes(请求 content-type)
        • produces(响应 Accept/Content-Type)
    • 参数绑定
      • 请求行/URL/Query/Form 类
        • @PathVariable:从 URL 路径中取值
        • @RequestParam:从 queryString 或表单中取值
        • @RequestHeader:从 header 取值
        • @CookieValue:从 cookie 取值
        • HttpServletRequest/Response、Principal 等:直接注入
        • 默认绑定
          • 对简单类型:往往当做 @RequestParam
          • 对复杂类型:走 @ModelAttribute 逻辑,把 query/form 参数按字段名绑定进去
      • @RequestBody (正文序列化)
        • 请求体 (JSON) 通过 HttpMessageConverter 反序列化成对象
        • 常见错误
          • Content-Type 不是 application/json
          • 字段类型不匹配导致 HtppMessageNotReadableException
          • 缺少无餐构造器/反序列化失败
    • 类型转换与校验
      • 类型转换链路
        • ConversionService:负责类型转换
        • Converter/Formatter:自定义转换规则
      • 校验 JSR-303
        • @Valid/@Validated
        • 常见异常
          • MethodArgumentNotValidException(@RequestBody + @Valid)
          • BindException(@ModelAttribute 绑定错误)
        • 配合 @ControllerAdvice 做统一错误响应
    • 返回值处理
      • 常见返回类型
        • String:视图名
        • ModelAndView:显式指定视图和模型
        • ResponseEntity:最推荐的 REST 返回方式之一,可控状态码/headers/body
        • T + @ResponseBody:直接序列化成 JSON
      • 返回值处理关键点
        • @RestController = @Controller + @ResponseBody
        • 选择哪个 converter 取决于
          • 返回对象类型
          • Accept 头
          • produces 配置
    • 异常处理体系
      • HandlerExceptionResolver 链
        • 按顺序尝试解析异常
          • ExecptionHandlerExceptionResolver:处理 @ExceptionHandler/@ControllerAdvice
          • ResponseStatusExceptionResolver:处理 @ResponseStatus
          • DefaultHandlerExceptionResolver:处理框架内置异常
      • @ControllerAdvice 正确用法
        • 全局异常 -> 统一 error code + message + traceId
        • 参数校验异常 -> 返回字段级错误列表
        • 业务异常 -> 返回业务错误码
        • 兜底异常 -> 返回 500 + 记录日志
    • Filter vs Interceptor
      • Filter(Servlet 规范)
        • 发生在 Servlet 容器层面
        • 能包裹整个请求响应链
        • 用于:编码/CORS/鉴权/请求体包装/日志 traceId 注入
      • Interceptor(Spring MVC)
        • 发生在 Handler 执行前后,更靠近 Controller
        • 包含三段内容
          • preHandler(调用前)
          • postHandler(方法返回后,视图渲染前)
          • afterCompletion(整个请求完成后,用于清理资源/记录异常)
        • Filter 是容器级,Interceptor 是框架级,能拿到 HandlerMethod,适合做与业务 Handler 相关的逻辑

Spring boot (自动配置、启动过程、外部化配置)

  • Spring boot
    • 解决了什么问题
      • Boot 的核心价值是:约定优于配置+自动配置+Starter依赖聚合
      • Starter:把一组常用的依赖按照场景打包
      • Auto-Configuration:根据 classpath、bean、配置项等条件自动创建 Bean
      • Externalized Configuration:同一的多来源配置体系
      • Production-ready:Actuator、metrics、health、logging 等
    • @SpringBootApplication 注解做了什么
      • @SpringBootConfiguration 本质就是 @Configuration
      • @ComponentScan 默认扫描启动类所在包及其子包
      • @EnableAutoConfiguration:开启自动配置导入
    • 自动配置原理
      • 概述
        • Boot 会在启动阶段把候选自动配置类加载进容器,但是不是无脑全开,而是通过大量的 @Conditional 做条件装配
          • 类路径上有没有哪个类
          • 容器里有没有某个 Bean
          • 配置属性是否存在且满足
          • 是否 Web 环境、是否 Servlet/Reactive
      • 自动配置类从哪里来
        • 自动配置类的来源本质是声明式列表,Boot 在启动时读取他们并导入
        • Boot 在启动阶段通过自动配置导入机制读取 classpath 上各个 starter 提供的自动配置声明,然后把这些自动配置类作为配置类导入容器;最终每个自动配置类再通过 @Conditional 决定是否生效
      • 条件注解
        • @ConditionalOnClass(A.class):classpath 有 A 才启动
        • @ConditionalOnMissingBean(X.class):容器里没有 X 才创建默认实现
        • @ConditionalOnBean(Y.class):必须已存在 Y 才启用
        • @ConditionalOnProperty(prefix=“a”, name=“b)
        • @ConditionalOnWebApplication
      • 自动配置覆盖/接管机制
        • Boot 默认提供一个 Bean,例如某个 DataSource
        • 只要自己定义同类型 Bean,通常由于自动配置里用了 @ConditionalOnMissingBean,默认不会创建
    • 启动过程
      • 启动过程的分段
        • 构建 SpringApplication
          • 推断应用类型:Servlet/Reactive/None
          • 加载初始化器/监听器(Initializers/Listeners)
        • 准备 Environment
          • 读取配置源:application.yml、环境变量、命令行参数、profile 等
          • 绑定 spring.* 相关关键属性(例如 banner、log、profiles)
        • 创建 ApplicationContext
          • Servlet Web:AnnotationConfigStyleWebServletApplicationContext
          • Reactive Web:对于 reactive context
        • 准备 Context
          • 注册启动类
          • 执行 ApplicationContextInitializer
        • 刷新 Context
          • 进入 Spring Core 经典流程
          • 自动配置也在这一阶段被导入并参与 Bean 创建
        • 启动 WebServer
        • 发布 ApplicationReadyEvent
          • 应用可以对外提供服务
    • 外部化配置
      • 配置来源
        • application.properties/application.yml
        • profile 文件:application-dev.yml
        • 环境变量 ENV
        • JVM 系统属性(-Dkey=value)
        • 命令行参数(–key=value)
      • 优先级
        • 越靠近运行时/越具体的优先级越高
        • 命令行/系统属性/环境变量高于配置文件
        • profile 配置文件会在激活 profile 后叠加
      • Boot 会把多来源配置汇总成 Environment 的 PropertySources,按优先级从高到低解析;同名 key 取最高优先级来源的值
      • Profile
        • 激活方式
          • spring.profiles.active=dev
          • –spring.profiles.active=dev
          • 环境变量
        • 生效规则
          • application.yml 的默认块+application-dev.yml 覆盖叠加
    • 配置绑定 @ConfigurationProperties
      • 对比 @Value
        • @Value:零散,难管理,不支持复杂层级/校验/IDE提示弱
        • @ConfigurationProperties:可以把一个前缀下的配置绑定到一个对象,支持嵌套、集合、校验

数据访问整合

  • 数据访问整合
    • 通用底座
      • DataSource:连接的来源
        • DataSource 是连接池的抽象
        • Spring 从 DataSource 拿 Connection,但事务期间会把 Connection 绑定到线程,避免每次 DAO 都新拿连接
      • 事务贯穿的关键:TransactionSynchronizationManager(TSM)
        • 开启事务时:取连接->setAutoCommit(false)->bind 到线程
        • DAO 执行时:通过 Spring 提供的工具从线程拿到同一连接
        • 提交/回滚后:解绑并释放连接
      • 同一异常体系:DataAccessException
        • Spring 会把各类底层异常统一成 DataAccessException 体系
        • 屏蔽不同驱动/框架的异常差异
        • 让事务默认回滚更符合直觉
    • JDBC: JdbcTemplate
      • JdbcTemplate 的价值
        • 封装样板代码:拿连接、创建 statement、执行、关闭资源、异常翻译
        • 与 Spring 事务自然融合:事务内复用同一连接
    • MyBatis 与 Spring 集成
      • MyBatis 的核心对象
        • SqlSessionFactory:会话工厂
        • SqlSession:一次会话(执行 SQL 的入口)
        • Mapper:接口代理,最终通过 SqlSession 执行
        • Executor:执行器(缓存、批处理等)
      • Spring-MyBatis 如何整合
        • Spring 提供 SqlSessionTemplate
        • 在事务中,通过 Spring 的事务同步机制把 SqlSession 与当前事务绑定
        • 事务提交/回滚时,SqlSession 会随着事务一起 commit/rollback
      • Mapper 扫描与处理
        • @MapperScan 会注册 Mapper 接口代理 Bean
        • 调用 Mapper 方法 -> 代理 -> SqlSessionTemplate -> 执行 SQL

Spring Security

  • Spring Security
    • 核心概念
      • SecurityContext:安全上下文,存当前请求/线程的认证信息
      • Authentication:一次认证的结果对象
        • principle:用户主体(UserDetail 或 userId)
        • credentials:凭证(密码/token)
        • authorities:权限集合(角色/权限点)
        • authenticated:是否已认证
      • SecurityContextHolder:存取 SecurityContext,默认 ThreadLocal
      • 认证成功后,SecurityContextHolder 里面会有 Authentication,后续授权判断都基于它
      • UserDetails 体系
        • UserDetails:用户信息抽象(用户名、密码、权限、是否过期)
        • UserDetailsService:按用户名加载用户
        • PasswordEncoder:密码编码/校验
    • 过滤器链:SecurityFilterChain
      • 请求进入一堆 SecurityFilters 才会进入到 SpringMVC
    • 认证机制
      • AuthenticationManager/ProviderManager
        • AuthenticationManager:认证入口
        • 常用实现:ProviderManager 内部持有多个 AuthenticationProvider
        • AuthenticationProvider:一种认证方式的具体实现
      • 认证流程
        • 过滤器拿到凭证,构造一个未认证的 Authentication
        • 交给 AuthenticationManager
        • ProviderManager 遍历 Providers,找到 supports 的 provider
        • provider 校验成功 -> 返回已认证的 Authentication
        • 写入 SecurityContexHolder
        • 后续授权阶段使用
    • 授权机制
      • authorities/roles 的关系
        • Spring Security 里面权限统一叫做 GrantedAuthority
        • 角色以 ROLE_ 前缀表示
          • hasRole(“ADMIN”) 等价于检查 authority ROLE_ADMIN
          • hasAuthority(“xxx:read”) 检查精确权限点
      • URL 级授权