个人主页:一条泥憨鱼(欢迎各位大佬莅临)精选专栏:数据结构与算法Java ,苍穹外卖日记AI学习JavaWeb前言刚接触 Spring 的时候很多同学都会有这样的疑问Transactional public void saveUser() { // 保存用户 }明明方法里面只有业务代码。为什么事务会自动开启为什么异常后还能自动回滚再比如Log public void login() { // 登录逻辑 }日志为什么会自动打印难道 Spring 偷偷修改了我们的代码事实上这背后都离不开一个非常重要的思想AOPAspect Oriented Programming面向切面编程很多人第一次学 AOP 时会被各种名词绕晕切面Aspect切点PointCut通知Advice连接点JoinPoint织入Weaving看完一脸懵。今天我们不用官方术语轰炸而是用人话彻底搞懂 AOP。什么是 AOP先说结论AOP 本质上是在不修改原有代码的情况下给代码额外增加功能。你可以理解成原功能 额外功能 增强后的功能例如原来的登录方法public void login() { System.out.println(用户登录); }现在老板要求记录日志统计耗时权限校验传统写法public void login() { System.out.println(开始记录日志); long start System.currentTimeMillis(); System.out.println(权限校验); System.out.println(用户登录); long end System.currentTimeMillis(); System.out.println(耗时 (end - start)); }业务代码越来越乱。这时候 AOP 就出现了。为什么需要 AOP举个真实开发场景。代码会大量重复。这违反了DRYDont Repeat Yourself不要重复自己。所以AOP 专门负责处理这些公共逻辑。业务代码专心处理业务。AOP 的核心思想可以把 AOP 理解成主业务 主菜 AOP 调料炒菜的时候先炒菜 再放盐 再放酱油菜本身没变只是额外增加了味道。AOP 也是一样原方法 ↓ 执行前增强 ↓ 执行方法 ↓ 执行后增强AOP 核心概念1、JoinPoint连接点简单理解可以被增强的方法例如public void login(){} public void register(){} public void update(){}这些方法都属于 JoinPoint。2、PointCut切点连接点有很多。但我们不一定全部增强。例如com.demo.service.*只增强 service 包下的方法。这就是切点。3、Advice通知增强逻辑。例如打印日志 权限校验 事务处理都属于 Advice。4、Aspect切面切面 切点 通知例如日志切面包含切哪些方法 执行什么增强5、Weaving织入把增强逻辑插入目标方法的过程。就叫织入。Spring AOP 工作流程用户调用userService.login();实际上执行流程调用代理对象 ↓ 执行前置通知 ↓ 执行目标方法 ↓ 执行后置通知 ↓ 返回结果流程用户 ↓ 代理对象 ↓ 前置通知 ↓ 目标方法 ↓ 后置通知 ↓ 返回结果Spring AOP 底层原理很多面试都会问Spring AOP 是怎么实现的答案动态代理。主要有两种方式。JDK 动态代理当类实现接口时public interface UserService { void login(); }Spring 会使用JDK Dynamic Proxy生成代理对象。CGLIB 动态代理如果没有接口public class UserService { }Spring 使用CGLIB通过继承生成子类。例如class UserServiceProxy extends UserService重写方法实现增强。AOP 实战案例第一步导入依赖SpringBoot 项目dependency groupIdorg.springframework.boot/groupId artifactId spring-boot-starter-aop /artifactId /dependency第二步业务类Service public class UserService { public void login() { System.out.println(用户登录); } }第三步创建切面Aspect Component public class LogAspect { /** * 切点表达式 * 匹配service包下所有方法 */ Pointcut(execution(* com.demo.service.*.*(..))) public void pointCut(){} /** * 前置通知 */ Before(pointCut()) public void before(){ System.out.println(方法执行前); } /** * 后置通知 */ After(pointCut()) public void after(){ System.out.println(方法执行后); } }第四步运行结果方法执行前 用户登录 方法执行后可以看到业务代码没有改。日志自动增加了。常见通知类型Before方法执行前。Before适合参数校验 权限校验 日志记录After方法执行后。AfterAfterReturning正常返回后执行。AfterReturningAfterThrowing出现异常时执行。AfterThrowing适合异常日志 报警通知Around最强大的通知。Around既能执行前增强也能执行后增强还能控制方法是否执行。示例Around(pointCut()) public Object around( ProceedingJoinPoint joinPoint) throws Throwable { System.out.println(开始); Object result joinPoint.proceed(); System.out.println(结束); return result; }实际开发中的应用场景日志系统记录接口访问日志。请求时间 请求参数 返回结果事务管理最经典应用。Transactional底层就是 AOP。权限校验例如AdminOnly自动验证管理员权限。接口限流防止恶意请求。性能统计统计接口耗时。订单接口120ms 支付接口300msAOP 优缺点优点代码解耦业务与公共逻辑分离。提高复用性日志只写一次全项目使用。易于维护修改切面即可。开发效率高事务、日志自动完成。缺点调试困难增强逻辑隐藏。新手容易找不到代码执行位置。性能有损耗需要生成代理对象。不过影响非常小。过度使用会复杂切面太多日志切面 事务切面 权限切面 缓存切面容易搞不清执行顺序。扩展1、什么是 AOPAOP 是一种面向切面编程思想用于在不修改源码的情况下对程序进行增强。2、Spring AOP 底层实现原理动态代理。包括JDK动态代理 CGLIB动态代理3、JDK 动态代理和 CGLIB 区别JDK必须实现接口CGLIB通过继承实现代理4、Transactional 为什么能生效因为 Spring 使用 AOP 创建代理对象。在方法执行前开启事务。执行后提交事务。异常时回滚事务。5、AOP 和 OOP 的区别OOP纵向抽取例如UserService OrderServiceAOP横向抽取例如日志 事务 权限总结如果用一句话概括 AOPAOP 就是在不修改原有代码的情况下为程序动态增加功能。从开发角度来看AOP 公共逻辑统一管理从底层角度来看AOP 动态代理从实际项目来看日志 事务 权限 监控 限流几乎都离不开 AOP。学会 AOP 后我们会发现 Spring 中很多“自动完成”的功能其实本质上都是切面增强。
Spring AOP 详解:为什么日志、事务都能自动执行?看完彻底搞懂 AOP
个人主页:一条泥憨鱼(欢迎各位大佬莅临)精选专栏:数据结构与算法Java ,苍穹外卖日记AI学习JavaWeb前言刚接触 Spring 的时候很多同学都会有这样的疑问Transactional public void saveUser() { // 保存用户 }明明方法里面只有业务代码。为什么事务会自动开启为什么异常后还能自动回滚再比如Log public void login() { // 登录逻辑 }日志为什么会自动打印难道 Spring 偷偷修改了我们的代码事实上这背后都离不开一个非常重要的思想AOPAspect Oriented Programming面向切面编程很多人第一次学 AOP 时会被各种名词绕晕切面Aspect切点PointCut通知Advice连接点JoinPoint织入Weaving看完一脸懵。今天我们不用官方术语轰炸而是用人话彻底搞懂 AOP。什么是 AOP先说结论AOP 本质上是在不修改原有代码的情况下给代码额外增加功能。你可以理解成原功能 额外功能 增强后的功能例如原来的登录方法public void login() { System.out.println(用户登录); }现在老板要求记录日志统计耗时权限校验传统写法public void login() { System.out.println(开始记录日志); long start System.currentTimeMillis(); System.out.println(权限校验); System.out.println(用户登录); long end System.currentTimeMillis(); System.out.println(耗时 (end - start)); }业务代码越来越乱。这时候 AOP 就出现了。为什么需要 AOP举个真实开发场景。代码会大量重复。这违反了DRYDont Repeat Yourself不要重复自己。所以AOP 专门负责处理这些公共逻辑。业务代码专心处理业务。AOP 的核心思想可以把 AOP 理解成主业务 主菜 AOP 调料炒菜的时候先炒菜 再放盐 再放酱油菜本身没变只是额外增加了味道。AOP 也是一样原方法 ↓ 执行前增强 ↓ 执行方法 ↓ 执行后增强AOP 核心概念1、JoinPoint连接点简单理解可以被增强的方法例如public void login(){} public void register(){} public void update(){}这些方法都属于 JoinPoint。2、PointCut切点连接点有很多。但我们不一定全部增强。例如com.demo.service.*只增强 service 包下的方法。这就是切点。3、Advice通知增强逻辑。例如打印日志 权限校验 事务处理都属于 Advice。4、Aspect切面切面 切点 通知例如日志切面包含切哪些方法 执行什么增强5、Weaving织入把增强逻辑插入目标方法的过程。就叫织入。Spring AOP 工作流程用户调用userService.login();实际上执行流程调用代理对象 ↓ 执行前置通知 ↓ 执行目标方法 ↓ 执行后置通知 ↓ 返回结果流程用户 ↓ 代理对象 ↓ 前置通知 ↓ 目标方法 ↓ 后置通知 ↓ 返回结果Spring AOP 底层原理很多面试都会问Spring AOP 是怎么实现的答案动态代理。主要有两种方式。JDK 动态代理当类实现接口时public interface UserService { void login(); }Spring 会使用JDK Dynamic Proxy生成代理对象。CGLIB 动态代理如果没有接口public class UserService { }Spring 使用CGLIB通过继承生成子类。例如class UserServiceProxy extends UserService重写方法实现增强。AOP 实战案例第一步导入依赖SpringBoot 项目dependency groupIdorg.springframework.boot/groupId artifactId spring-boot-starter-aop /artifactId /dependency第二步业务类Service public class UserService { public void login() { System.out.println(用户登录); } }第三步创建切面Aspect Component public class LogAspect { /** * 切点表达式 * 匹配service包下所有方法 */ Pointcut(execution(* com.demo.service.*.*(..))) public void pointCut(){} /** * 前置通知 */ Before(pointCut()) public void before(){ System.out.println(方法执行前); } /** * 后置通知 */ After(pointCut()) public void after(){ System.out.println(方法执行后); } }第四步运行结果方法执行前 用户登录 方法执行后可以看到业务代码没有改。日志自动增加了。常见通知类型Before方法执行前。Before适合参数校验 权限校验 日志记录After方法执行后。AfterAfterReturning正常返回后执行。AfterReturningAfterThrowing出现异常时执行。AfterThrowing适合异常日志 报警通知Around最强大的通知。Around既能执行前增强也能执行后增强还能控制方法是否执行。示例Around(pointCut()) public Object around( ProceedingJoinPoint joinPoint) throws Throwable { System.out.println(开始); Object result joinPoint.proceed(); System.out.println(结束); return result; }实际开发中的应用场景日志系统记录接口访问日志。请求时间 请求参数 返回结果事务管理最经典应用。Transactional底层就是 AOP。权限校验例如AdminOnly自动验证管理员权限。接口限流防止恶意请求。性能统计统计接口耗时。订单接口120ms 支付接口300msAOP 优缺点优点代码解耦业务与公共逻辑分离。提高复用性日志只写一次全项目使用。易于维护修改切面即可。开发效率高事务、日志自动完成。缺点调试困难增强逻辑隐藏。新手容易找不到代码执行位置。性能有损耗需要生成代理对象。不过影响非常小。过度使用会复杂切面太多日志切面 事务切面 权限切面 缓存切面容易搞不清执行顺序。扩展1、什么是 AOPAOP 是一种面向切面编程思想用于在不修改源码的情况下对程序进行增强。2、Spring AOP 底层实现原理动态代理。包括JDK动态代理 CGLIB动态代理3、JDK 动态代理和 CGLIB 区别JDK必须实现接口CGLIB通过继承实现代理4、Transactional 为什么能生效因为 Spring 使用 AOP 创建代理对象。在方法执行前开启事务。执行后提交事务。异常时回滚事务。5、AOP 和 OOP 的区别OOP纵向抽取例如UserService OrderServiceAOP横向抽取例如日志 事务 权限总结如果用一句话概括 AOPAOP 就是在不修改原有代码的情况下为程序动态增加功能。从开发角度来看AOP 公共逻辑统一管理从底层角度来看AOP 动态代理从实际项目来看日志 事务 权限 监控 限流几乎都离不开 AOP。学会 AOP 后我们会发现 Spring 中很多“自动完成”的功能其实本质上都是切面增强。