学习日记-spring-day42-7.7

知识点:

1.Spring AOP 快速入门(1)

|-------------|-------------------------------------|---------------------------|
| 知识点 | 核心内容 | 重点 |
| AOP编程概念 | 使用Spring AOP实现动态代理效果,替代手动实现方式 | 区分手动代理与Spring AOP实现机制 |
| 切面类注解 | @Component+@Aspect双注解标识切面类 | 必须同时使用两个注解才能生效 |
| 前置通知实现 | @Before注解+execution表达式定义切入点 | execution表达式格式要求严格 |
| 连接点对象 | JoinPoint参数获取方法签名和执行参数 | 与反射API的Method对象区别 |
| 依赖包配置 | aspectjweaver.jar等5个新增依赖包 | 遗漏aspects包导致功能失效 |
| 切入点表达式 | execution(访问修饰符 返回类型 全类名.方法名(参数列表)) | 参数列表必须带完整类型声明 |
| 动态代理机制 | Spring AOP底层仍基于动态代理+反射实现 | 与传统JDK动态代理的关系 |
| 切面方法命名 | 可自定义方法名(如showBeginLog) | 与通知类型无强制命名关联 |

2.Spring AOP 快速入门(2)

|----------------|----------------------------------------------------|-----------------------------------------|
| 知识点 | 核心内容 | 重点 |
| Spring注解扫描 | 使用<context:component-scan>标签扫描指定包路径下的组件 | 包路径必须准确,需包含com.aop.aspect层级 |
| AOP注解配置 | @Aspect注解标记切面类,@Component标记被代理类 | 需配合**<aop:aspectj-autoproxy/>启用注解功能 |
| 代理对象获取 | 通过接口类型从IOC容器获取
动态代理对象** | 实际获取的是SmartDog的代理实例,非原始对象 |
| 依赖注入问题排查 | 1. 检查包扫描范围; 2. 确认AOP注解开关; 3. 排查错误包引用(如接口误引其他包) | 类型转换异常多由包引用错误导致 |
| 切面类功能对比 | Spring AOP比手动编写的MyProxyProvider功能更强大 | 自动处理动态调用等底层逻辑 |
| 接口注入实践 | 推荐通过接口类型获取bean(如SmartAnimalable) | 需确保实现类与接口同包,避免引用冲突 |

3.Spring AOP 快速入门(3)

|---------------|------------------------------------------------------------------------------------------|-----------------------------------|
| 知识点 | 核心内容 | 重点 |
| AOP切面编程原理 | 通过动态代理实现方法拦截,前置通知(@Before)、返回通知(@AfterReturning)、异常通知(@AfterThrowing)、最终通知(@After)四种通知类型 | 代理对象获取方式必须通过接口类型,直接按实现类获取会报错 |
| 动态代理运行机制 | Spring AOP底层采用动态代理,返回的是代理对象而非原始对象 | 代理对象与原始对象类型差异,SmartDog类无法直接接收代理对象 |
| 切面类设计规范 | 1. 避免使用静态方法; 2. 通知方法命名需明确功能定位; 3. 输出信息需标注切面来源 | 静态方法与非静态方法在切面中的适用场景区别 |
| 异常通知触发条件 | 通过@AfterThrowing在目标方法抛出异常时执行,演示代码使用int res=9/0强制触发算术异常 | 异常类型匹配规则与try-catch块执行逻辑的对应关系 |
| 最终通知特性 | @After通知无论目标方法是否异常都会执行,类比finally代码块 | 与返回通知(@AfterReturning)的执行顺序差异 |
| 代理对象类型验证 | 通过System.out.println(bean.getClass())输出运行类型为com.sun.proxy.$Proxy | 接口代理与CGLIB代理的获取方式区别 |

4.Spring AOP 快速入门注意事项(1)

|---------------|--------------------------------------------------------------|------------------------------------------|
| 知识点 | 核心内容 | 重点 |
| AOP方法命名规范 | 方法命名需体现横切关注点位置(如前置/后置/异常通知),示例:showBeginLog替代f1 | 命名与实际切入逻辑的匹配性(如showSuccessEndLog需对应返回通知) |
| 切入点表达式配置 | 支持灵活匹配(如*匹配所有方法,..匹配任意参数),示例:* com.example.SmartDog.*(..) | 模糊匹配范围(如*.*.*会覆盖所有类方法,需谨慎使用) |
| 动态代理机制 | 底层通过动态代理实现参数传递和切入逻辑(如获取float形参值) | 代理对象与原对象调用差异(需扫描的Bean才生效) |
| AOP应用场景 | 日志记录、事务管理等横切关注点(文中提及声明式事务将用到) | 与OOP编程思想的本质区别(颠覆性) |
| 异常处理切入 | 通过showExceptionLog捕获异常并输出日志 | 异常通知与最终通知(finally)的执行顺序 |

5.Spring AOP 快速入门注意事项(2)

|----------------------|-------------------------------------------|--------------------------|
| 知识点 | 核心内容 | 重点 |
| Spring AOP注解功能开启 | 必须添加<aop:aspectj-autoproxy/>标签,否则切面类不生效 | 标签遗漏导致代理失效 |
| 代理对象与原生对象区别 | 开启AOP后,注入对象为代理类型,原生对象仍保留在容器中 | 强制转回原生类型会报错 |
| 动态代理底层机制 | 等价于手动实现的getProxy方法,通过反射和动态绑定实现AOP | 需理解动态代理原理 |
| 接口类型注入必要性 | 必须通过接口类型获取注入对象,代理对象无法转为具体实现类 | ClassCastException风险 |
| ID获取注入对象限制 | 通过ID获取时仍需转为接口类型,直接转具体类会报错 | 代理类型与接口类型绑定 |

6.切入表达式具体使用

|-----------------|------------------------------------------|-------------------|
| 知识点 | 核心内容 | 重点 |
| AOP切入点表达式作用 | 通过表达式定位一个或多个连接点(即指定切面方法切入的目标类方法) | 连接点与切入点概念区分 |
| 表达式语法规则 | execution(修饰符 返回值类型 包名.类名/接口名.方法名(参数列表)) | 修饰符/返回值可省略(用*通配) |
| 包名省略条件 | 目标类与切面类在同一包下时可省略包名 | 需显式检查包路径 |
| 通配符用法 | - *匹配任意修饰符/返回值/方法名; - ..匹配任意数量/类型参数 | *与..的适用场景差异 |
| 接口方法匹配 | 表达式可指定接口名,匹配其所有实现类方法 | 接口名与类名混用场景 |
| 参数类型限定 | 如(double,..)匹配首个参数为double的方法 | 参数顺序敏感性问题 |
| IDE调试技巧 | IDEA通过箭头标记可视化切入关系(点击跳转目标方法) | 工具依赖性与通用性 |

7.切入表达式注意事项和细节(1)

|--------------------|-------------------------------------------------------------------|-------------------------------|
| 知识点 | 核心内容 | 重点 |
| 切入表达式指向类的方法 | 表达式作用于类的对象,生效范围仅限该类实例(如示例中的getSome、work方法) | 需明确区分类方法实例方法的切入范围 |
| 切入表达式指向接口的方法 | 表达式对所有实现接口的类对象生效(如USBInterface接口的work方法,其实现类Phone和Camera均被切入) | 接口与实现类的动态代理机制是关键易混淆点 |
| 配置方式的影响 | 直接配置类方法(如Phone.work)仅对该类生效;配置接口方法(如USBInterface.work)则覆盖所有实现类 | 配置粒度 决定作用范围,需注意重复配置问题 |
| 前置通知(Before)验证 | 通过注销/启用配置案例,演示hi方法仅切入Phone.work或同时切入Phone/Camera的work方法 | 动态调试是理解切入逻辑的核心手段 |

8.切入表达式注意事项和细节(2)

|---------------|-------------------------------------------------|------------------------------------------------|
| 知识点 | 核心内容 | 重点 |
| AOP切入机制 | 即使类未实现接口,仍可通过AOP切入(如Car类的run方法) | 前置通知配置:@Before注解与execution表达式匹配无接口类方法 |
| 动态代理类型对比 | JDK Proxy (面向接口) vs CGLib(面向父类) | 关键区别:JDK代理仅增强接口方法,CGLib可增强父类所有方法并生成子类代理对象 |
| CGLib代理特性 | 代理对象为被代理类的子类,支持读取父类方法注解 | 验证方式:输出car.getClass()显示$$EnhancerByCGLIB后缀 |
| AOP配置实践 | 通过@Component注入无接口类,@Aspect定义切面方法(如ok1) | 易错点:包路径简写需确保切面类与目标类同包 |
| 动态代理底层原理 | JDK Proxy基于InvocationHandler,CGLib通过方法拦截器实现功能增强 | 核心价值:不修改源码实现方法增强(如日志、权限校验) |

9.JoinPoint

|-----------------|-------------------------------------------------------------------------------|--------------------------------------------|
| 知识点 | 核心内容 | 重点 |
| AOP通知类型 | 前置通知(@Before)、返回通知(@AfterReturning)、异常通知(@AfterThrowing)、后置通知(@After)的配置与执行顺序 | 返回通知与后置通知的区别(返回通知仅在方法正常返回时触发) |
| JoinPoint对象 | 通过JoinPoint获取方法签名、类名、参数、修饰符等信息,支持动态代理调试 | getTarget()与getThis()的区别(目标对象 vs 代理对象) |
| 切面类调试 | 通过断点演示JoinPoint的getSignature()、getArgs()等方法,验证代理对象类型 | 修饰符数字编码(如1=public)需记忆 |
| 动态代理实现 | 代理对象继承目标类(如Car$Proxy),通过切面类增强原方法逻辑 | 代理对象与目标对象的父子类关系 |

10.返回通知获取结果

|-----------------------|----------------------------------------------|-----------------------|
| 知识点 | 核心内容 | 重点 |
| AOP返回通知机制 | 通过@AfterReturning注解的returning属性获取目标方法返回值 | 注解参数名与切入方法参数名必须一致 |
| 切面编程执行流程 | 代理对象通过反射执行目标方法→捕获返回值→传递给切入方法 | 理解动态代理底层实现机制 |
| @AfterReturning注解 | 包含value(切入点)和returning(返回值绑定)两个关键属性 | returning属性是可选配置项 |
| 返回值传递原理 | 底层通过反射机制将目标方法结果注入切入方法参数 | 类比手写切面类的after方法实现 |
| 通知类型限制 | 仅返回通知能获取方法返回值,前置通知等类型不支持 | 不同通知类型的适用场景区分 |
| 参数绑定验证 | 演示res/result2命名不一致导致的参数解析错误 | 编译时检查与运行时异常的区别 |

11.异常通知获取异常信息

|---------------|--------------------------------------------------------|-----------------------------------|
| 知识点 | 核心内容 | 重点 |
| AOP异常通知机制 | 在切面类中通过@AfterThrowing注解捕获目标方法抛出的异常,需配置throwing属性绑定异常变量 | throwing属性变量名需与切面方法参数名严格一致 |
| 异常信息获取 | 目标方法抛出异常后,切面方法通过Throwable类型参数接收异常对象,可打印或处理异常信息 | 异常类型需匹配(如示例中的ArithmeticException) |
| 动态代理关联 | 异常通知对应动态代理代码中的catch块,异常对象通过变量传递到切面方法 | 理解代理机制与AOP注解的映射关系 |
| 算术异常模拟 | 通过1/0强制触发ArithmeticException,演示异常通知的触发条件 | 需明确异常触发与通知执行的时序逻辑 |

相关推荐
界面开发小八哥1 小时前
「Java EE开发指南」如何用MyEclipse创建一个WEB项目?(三)
java·ide·java-ee·myeclipse
idolyXyz1 小时前
[java: Cleaner]-一文述之
java
一碗谦谦粉1 小时前
Maven 依赖调解的两大原则
java·maven
九年义务漏网鲨鱼1 小时前
【大模型学习 | MINIGPT-4原理】
人工智能·深度学习·学习·语言模型·多模态
jz_ddk2 小时前
[学习] C语言数学库函数背后的故事:`double erf(double x)`
c语言·开发语言·学习
netyeaxi2 小时前
Java:使用spring-boot + mybatis如何打印SQL日志?
java·spring·mybatis
收破烂的小熊猫~2 小时前
《Java修仙传:从凡胎到码帝》第四章:设计模式破万法
java·开发语言·设计模式
小七mod2 小时前
【MyBatis】MyBatis与Spring和Spring Boot整合原理
spring boot·spring·mybatis
猴哥源码2 小时前
基于Java+SpringBoot的动物领养平台
java·spring boot
老任与码2 小时前
Spring AI Alibaba(1)——基本使用
java·人工智能·后端·springaialibaba