学习日记-spring-day43-7.8
知识点:
1.环绕通知
知识点 | 核心内容 | 重点 |
环绕通知概念 | 整合前置、返回、异常、最终四种通知的统一管理方式 | 与单独四种通知的区别与联系 |
环绕通知实现 | 使用@Around注解 + ProceedingJoinPoint参数实现 | proceed()方法调用时机与返回值处理 |
代码结构特点 | 采用try-catch-finally结构整合四种通知逻辑 | 各代码块对应原通知类型的映射关系 |
多切面冲突 | 多个切面类同时生效会导致重复执行 | @Component和@Aspect注解的生效机制 |
动态代理原理 | 底层仍通过反射机制调用目标方法 | 代理对象与原始方法的调用链路 |
异常处理演示 | catch块模拟异常通知场景 | 异常触发条件与通知执行顺序 |
切面表达式 | value属性指定切入点表达式 | 通配符使用规范与匹配规则 |
2.切入表达式重用
知识点 | 核心内容 | 重点 |
AOP环绕通知 | 只需了解基本概念,非本节课重点 | 与其他通知类型的执行顺序差异 |
切入点表达式重用 | 使用@Pointcut注解定义可复用的切入点表达式 | 注解value属性配置与常规通知配置差异 |
前置通知配置 | @Before+value指定切入点 | 需保持双引号格式规范 |
返回通知配置 | @AfterReturning需额外配置returning参数 | 参数名必须与切入方法变量名一致 |
异常通知配置 | @AfterThrowing需配置throwing参数 | 异常类型匹配机制 |
最终通知配置 | @After基础配置方式 | 与返回/异常通知执行顺序关系 |
复用验证方法 | 通过统一切入点方法名(myPointCut)引用 | 多通知共用时的参数传递机制 |
3.切面类执行顺序
知识点 | 核心内容 | 重点 |
AOP切面优先级控制 | 通过@Order注解的value值控制多个切面类的执行顺序,值越小优先级越高 | 执行顺序规则:前置通知按优先级升序,后置通知按优先级降序(类似过滤器链) |
@Order注解使用 | 需确保引入org.springframework.core.annotation.Order,默认值为Integer.MAX_VALUE(最低优先级) | 易错点:误引入其他包(如JUnit的Order)导致配置失效 |
多切面执行现象 | 同一方法被多个切面切入时,前置通知按优先级升序执行,后置通知(返回/最终)按优先级降序执行 | 关键现象:后置通知执行顺序与前置通知相反 |
代码演示逻辑 | 通过SmartAnimalAspect和SmartAnimalAspect3两个切面类,动态调整@Order值观察执行顺序变化 | 对比维度:value=1 vs value=2 的切面类执行顺序差异 |
4.切面类执行顺序
知识点 | 核心内容 | 重点 |
AOP切面编程执行顺序 | 通过order值决定切面类执行优先级,order值越小越先执行前置通知 | 执行顺序理解:前置通知按order顺序→目标方法→返回通知/异常通知/最终通知按逆序 |
切面类结构 | 包含前置通知、返回通知、异常通知、最终通知四个横切关注点 | 需明确每个通知类型的触发时机和功能差异 |
动态代理机制 | 底层采用动态代理和反射实现切面逻辑 | 与过滤器链式调用机制高度相似 |
多切面类协同 | 当存在多个切面类时,按order值形成嵌套执行链 | 关键点:前置通知正序执行,后置通知逆序执行 |
5.基于XML配置的AOP(1)
知识点 | 核心内容 | 重点 |
AOP编程方式 | 基于XML配置与注解方式的对比与实现 | XML配置的组件注入逻辑 vs 注解自动扫描 |
Spring容器管理 | 非注解组件的XML配置注入 | NoSuchBeanDefinitionException 触发条件与解决 |
AOP切面编程 | XML配置切面的步骤(接口、实现类、测试用例) | 注解注销后的显式XML配置必要性 |
代码实践演示 | smartDog 组件从注解迁移到XML的完整流程 | 命名空间与标签的作用域验证 |
6.基于XML配置的AOP(2)
知识点 | 核心内容 | 重点 |
AOP编程基础 | 使用XML配置实现AOP(面向切面编程) | XML配置与注解配置的区别 |
切面类配置 | 通过<bean>标签定义切面类对象 | 切面类需移除@Component等注解 |
切入点表达式 | 在XML中通过<aop:pointcut>定义切入点 | 表达式语法需与注解配置一致 |
通知类型配置 | XML标签对应不同通知类型: - <aop:before>(前置); - <aop:after-returning>(返回); - <aop:after-throwing>(异常); - <aop:after>(最终) | 参数传递(如returning/throwing属性) |
命名空间依赖 | 必须引入aop命名空间才能使用相关标签 | 缺失命名空间导致配置失效 |
环绕通知 | 可通过<aop:around>配置(文中未演示) | 需处理ProceedingJoinPoint参数 |
7.基于XML配置的AOP(3)
知识点 | 核心内容 | 重点 |
AOP切面配置 | 通过XML配置切面类对象,类比@Component注解的作用 | XML配置与注解方式的等效性(如<bean> vs @Component) |
切点表达式 | aop:pointcut配置,对应切面类中的方法拦截规则 | 路径匹配的准确性(如包名、类名、方法名层级) |
通知类型 | 前置通知、返回通知、异常通知、最终通知的XML配置 | 执行顺序(order属性)与通知类型的作用域 |
接口引用错误 | 因包路径错位导致SmartAnimal接口未正确加载 | 复现场景:代码拷贝时IDE自动补全的包路径差异 |
调试与验证 | 通过输出XML配置标识验证AOP生效,对比运行日志定位问题 | 关键排查点:Bean加载日志与异常堆栈信息分析 |
8.实现Spring底层机制-说明
知识点 | 核心内容 | 重点 |
AOP编程实现 | 使用注解和XML配置两种方式实现AOP,在方法执行前后打印时间日志 | 注解配置与XML配置的语法差异 |
接口与实现类 | 定义Calculator接口(含calc1和calc2方法),实现类MyCalculator需完成累加和阶乘功能 | 接口方法的强制实现规则 |
时间日志打印 | 在calc1和calc2方法执行前后,通过AOP统一打印开始时间和结束时间 | 时间格式处理(如毫秒转可读格式) |
作业要求分解 | 1. 编写接口与实现类 2. 分别用注解和XML实现AOP 3. 验证时间日志输出 | 注解与XML配置的优先级问题 |
9.搭建Java Maven项目
知识点 | 核心内容 | 重点 |
Spring依赖注入实现机制 | 通过@Autowired或@Resource注解实现属性自动装配,本质是对象间的引用关系组装(如A类属性a引用B类对象) | @Autowired与@Resource的区别、注入失败场景处理 |
单例(Singleton)与多例(Prototype)作用域 | 默认单例(容器内唯一对象),通过@Scope("prototype")配置多例(每次获取新实例) | 单例线程安全问题、多例适用场景(如请求级对象) |
Maven项目资源配置规则 | 配置文件需放在src/main/resources目录(普通Java项目放src下),否则类路径加载失败 | Maven标准目录结构、资源文件打包逻辑 |
组件扫描与注解 | @Component及其衍生注解(@Controller/@Service/@Repository)标记需扫描的类,context:component-scan配置扫描包路径 | 注解等效性、自定义扫描过滤规则 |
Bean名称默认规则 | 未指定Bean名称时,类名首字母小写作为容器中的标识(如UserDao→userDao) | 自定义Bean名称(@Component("自定义名")) |
10.抛出问题 依赖注入和单例多实例
知识点 | 核心内容 | 重点 |
Spring Scope配置 | 通过@Scope注解配置单例(singleton)或多例(prototype),默认单例 | XML配置与注解配置的区别 |
多例模式实现 | 配置@Scope("prototype")后,每次getBean()返回新实例 | 哈希值验证对象唯一性 |
依赖注入机制 | 使用@Autowired实现对象间自动装配,解决空指针问题 | 注解驱动与XML配置的注入方式对比 |
底层实现原理 | Spring容器如何通过注解实现单例/多例控制和依赖注入 | 手动实现机制与框架封装的关系 |
实践验证方法 | 通过哈希值对比验证单例/多例,通过方法调用验证依赖注入 | 测试用例设计要点 |
11.抛出问题 BeanPostProcessor
知识点 | 核心内容 | 重点 |
Spring后置处理器实现机制 | 通过实现BeanPostProcessor接口,在bean初始化前后插入自定义逻辑 | 初始化方法前后调用顺序与@PostConstruct注解关系 |
BeanPostProcessor接口方法 | postProcessBeforeInitialization和postProcessAfterInitialization两个核心方法 | 方法返回值处理(修改bean实例或返回原对象) |
初始化方法声明方式 | XML配置init-method属性 vs 注解@PostConstruct | 非标准命名方法如何被识别为初始化方法 |
作用域对处理器调用的影响 | 单例(singleton)与原型(prototype)模式下的调用次数差异 | 多例模式每次getBean都会触发完整生命周期 |
AOP底层关联 | 后置处理器作为AOP动态代理的实现基础 | 方法拦截时机与初始化阶段的关联性 |
调试验证方法 | 通过输出日志观察before/after与init方法的执行顺序 | 无init方法的bean是否触发处理器调用 |