Spring |(七)AOP概念及工作流程

ops/2024/11/28 16:47:11/

文章目录

  • 📚AOP简介
  • 📚AOP入门案例
    • 🐇环境准备
    • 🐇AOP实现步骤
  • 📚AOP工作流程
  • 📚小结

学习来源:黑马程序员SSM框架教程_Spring+SpringMVC+Maven高级+SpringBoot+MyBatisPlus企业实用开发技术

📚AOP简介

  • 一句话描述:AOP是在不改原有代码的前提下对其进行增强。

  • AOP(Aspect Oriented Programming)面向切面编程,一种编程范式,指导开发者如何组织程序结构。

  • 以下述代码为例,计算万次执行消耗时间的代码只有save有,但最后deleteupdate方法最终都执行了万次,这里就用到了AOP——在不惊动(改动)原有设计(代码)的前提下,想给谁添加功能就给谁添加。

    java">@Repository
    public class BookDaoImpl implements BookDao {public void save() {//记录程序当前执行执行(开始时间)Long startTime = System.currentTimeMillis();//业务执行万次for (int i = 0;i<10000;i++) {System.out.println("book dao save ...");}//记录程序当前执行时间(结束时间)Long endTime = System.currentTimeMillis();//计算时间差Long totalTime = endTime-startTime;//输出信息System.out.println("执行万次消耗时间:" + totalTime + "ms");}public void update(){System.out.println("book dao update ...");}public void delete(){System.out.println("book dao delete ...");}public void select(){System.out.println("book dao select ...");}
    }
    

    在这里插入图片描述

    • 对于上面的案例中BookServiceImpl中有saveupdatedeleteselect方法,这些方法叫连接点
    • 在BookServiceImpl的四个方法中,updatedelete只有打印没有计算万次执行消耗时间,但是在运行的时候已经有该功能,那也就是说updatedelete方法都已经被增强,所以对于需要增强的方法我们叫切入点
    • 执行BookServiceImpl的update和delete方法的时候都被添加了一个计算万次执行消耗时间的功能,将这个功能抽取到一个方法中,换句话说就是存放共性功能的方法,我们叫通知
    • 通知是要增强的内容,会有多个,切入点是需要被增强的方法,也会有多个,那哪个切入点需要添加哪个通知,就需要提前将它们之间的关系描述清楚,那么对于通知和切入点之间的关系描述,我们叫切面
    • 通知是一个方法,方法不能独立存在需要被写在一个类中,这个类叫通知类
      在这里插入图片描述
  • 归纳一下

    • 连接点(JoinPoint):程序执行过程中的任意位置,粒度为执行方法、抛出异常等。
    • 切入点(Pointcut):匹配连接点的式子。
    • 通知(Advice):在切入点处执行的操作,也就是共性功能
    • 通知类:定义通知的类。
    • 切面(Aspect):描述通知与切入点的对应关系。

📚AOP入门案例

🐇环境准备

在这里插入图片描述

  • 创建一个Maven项目。

  • pom.xml添加Spring依赖。

    <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.10.RELEASE</version></dependency>
    </dependencies>
    
  • 添加BookDao和BookDaoImpl类。

    java">public interface BookDao {public void save();public void update();
    }@Repository
    public class BookDaoImpl implements BookDao {public void save() {System.out.println(System.currentTimeMillis());System.out.println("book dao save ...");}public void update(){System.out.println("book dao update ...");}
    }
    
  • 创建Spring的配置类

    java">@Configuration
    @ComponentScan("com.itheima")
    public class SpringConfig {
    }
    
  • 编写App运行类

    java">public class App {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookDao bookDao = ctx.getBean(BookDao.class);bookDao.save();}
    }
    

需求:使用SpringAOP的注解方式完成在方法执行前打印出当前系统时间。

  • 目前打印save方法的时候,因为方法中有打印系统时间,所以运行的时候是可以看到系统时间。
  • update就没有该功能。我们要使用SpringAOP的方式在不改变update方法的前提下让其具有打印系统时间的功能。

🐇AOP实现步骤

  • 步骤1:pom.xml添加依赖。spring-context中已经导入了spring-aop,所以不需要再单独导入spring-aop。导入AspectJ的jar包,AspectJ是AOP思想的一个具体实现。
    <dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version>
    </dependency>
    
  • 步骤2:定义接口与实现类。这里沿用环境准备的部分,不作修改。
  • 步骤3:定义通知类和通知。通知即将共性功能抽取出来后形成的方法,共性功能指当前系统时间的打印。
    java">//类名和方法名任意
    public class MyAdvice {public void method(){System.out.println(System.currentTimeMillis());}
    }
    
  • 步骤4:定义切入点。切入点定义依托一个不具有实际意义的方法进行,即无参数、无返回值、方法体无实际逻辑。
    java">ublic class MyAdvice {@Pointcut("execution(void com.itheima.dao.BookDao.update())")private void pt(){}public void method(){System.out.println(System.currentTimeMillis());}
    }
    
  • 步骤5:制作切面。绑定切入点与通知关系,并指定通知添加到原始连接点的具体执行位置
    java">public class MyAdvice {@Pointcut("execution(void com.itheima.dao.BookDao.update())")private void pt(){}@Before("pt()")public void method(){System.out.println(System.currentTimeMillis());}
    }
    
    在这里插入图片描述
  • 步骤6:将通知类配给给容器并标识其为切面类。
    java">@Component
    @Aspect
    public class MyAdvice {@Pointcut("execution(void com.itheima.dao.BookDao.update())")private void pt(){}@Before("pt()")public void method(){System.out.println(System.currentTimeMillis());}
    }
    
  • 步骤7:开启注解格式AOP功能。
    java">@Configuration
    @ComponentScan("com.itheima")
    @EnableAspectJAutoProxy
    public class SpringConfig {
    }
    
  • 步骤8:运行程序。在执行update方法之前打印了系统时间戳,说明对原始方法进行了增强,AOP编程成功。
    java">public class App {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);BookDao bookDao = ctx.getBean(BookDao.class);bookDao.update();}
    }
    
    在这里插入图片描述

📚AOP工作流程

  • 流程1:Spring容器启动。
    • 容器启动就需要去加载bean,去加载那些需要被增强的类,如BookServiceImpl,通知类,如MyAdvice。
    • 注意此时bean对象还没有创建成功。
  • 流程2:读取所有切面配置中的切入点。
    • 下面这个例子中有两个切入点的配置。
    • 但第一个ptx()并没有被使用,所以不会被读取。
      在这里插入图片描述
  • 流程3:初始化bean,判定bean对应的类中的方法是否匹配到任意切入点。
    • 第1步在容器启动的时候,bean对象还没有被创建成功。
    • 要被实例化bean对象的类中的方法和切入点进行匹配。
      在这里插入图片描述
      • 匹配失败,创建原始对象,如UserDao。匹配失败说明不需要增强,直接调用原始对象的方法即可。
      • 匹配成功,创建原始对象(目标对象)代理对象,如BookDao
        • 匹配成功说明需要对其进行增强。对哪个类做增强,这个类对应的对象就叫做目标对象。
        • 因为要对目标对象进行功能增强,采用的技术是动态代理,所以会为其创建一个代理对象。
        • 最终运行的是代理对象的方法,在该方法中会对原始方法进行功能增强。
  • 流程4:获取bean执行方法。
    • 获取的bean是原始对象时,调用方法并执行,完成操作。
    • 获取的bean是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,完成操作。

目标对象(Target):原始功能去掉共性功能对应的类产生的对象,这种对象是无法直接完成最终工作的。
代理(Proxy):目标对象无法直接完成工作,需要对其进行功能回填,通过原始对象的代理对象实现。

📚小结

  • 知识点1:@EnableAspectJAutoProxy
    在这里插入图片描述
  • 知识点2:@Aspect
    在这里插入图片描述
  • 知识点3:@Pointcut
    在这里插入图片描述
  • 知识点4:@Before
    在这里插入图片描述

http://www.ppmy.cn/ops/137407.html

相关文章

深度学习与持续学习:人工智能的未来与研究方向

文章目录 1. 持续学习与深度学习1.1 深度学习的局限1.2 持续学习的定义 2. 目标与心智2.1 奖励假说2.2 心智的构成 3. 对研究方法的建议3.1 日常写作记录3.2 中立对待流行趋势 1. 持续学习与深度学习 1.1 深度学习的局限 深度学习注重“瞬时学习”&#xff0c;如ChatGPT虽在语…

Git 入门超简单指南

1. 什么是 Git&#xff1f; Git 是一个分布式版本控制系统&#xff0c;由 Linus Torvalds 于 2005 年创建。它的主要目的是帮助开发者有效地管理和跟踪项目的历史版本。通过使用 Git&#xff0c;你可以轻松地记录每一次代码的修改&#xff0c;回滚到以前的版本&#xff0c;以及…

javaweb-day02-JS(javascript)

1.JavaScript引入 &#xff08;1&#xff09;引入方式 2.JS语法 2.1 书写语法 2.2 变量 &#xff08;1&#xff09;var关键字定义的是全局变量&#xff1b; &#xff08;2&#xff09;可以重复声明&#xff1b; 2.3 数据类型&运算符 &#xff08;1&#xff09;数据类型…

钉钉授权登录

一.找开钉钉开发平台【钉钉开放平台 (dingtalk.com)】 二。点击菜单【应用开发】->左边【钉钉应用】->【创建应用】 三。创建应用-》保存成功后&#xff0c;点击自己【新建的应用】&#xff0c;进入详细页面 四。进入应用详细页面。左边【分享设置】 注意&#xff1a;进…

七牛云AIGC内容安全方案助力企业合规创新

随着人工智能生成内容(AIGC)技术的飞速发展,内容审核的难度也随之急剧上升。在传统审核场景中,涉及色情、政治、恐怖主义等内容的标准相对清晰明确,但在AIGC的应用场景中,这些界限变得模糊且难以界定。用户可能通过交互性引导AI生成违规内容,为审核工作带来了前所未有的不可预测…

VUE练习

使用new Vue()创建Vue实例&#xff0c;传入配置对象&#xff08;el data&#xff09; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial…

11.27作业

C语言关键概念 ├── static │ ├── 局部变量 │ │ └── 生命周期持续整个程序运行 │ └── 全局变量和函数 │ └── 仅在定义文件中可见 ├── extern │ └── 引入其他文件中的全局变量 ├── typedef │ ├── 类型重命名 │ │ ├─…

java——Tomcat连接池配置NIO、BIO、APR

Tomcat连接池的配置涉及不同的IO模型&#xff0c;包括NIO&#xff08;Non-blocking IO&#xff0c;非阻塞IO&#xff09;、APR&#xff08;Apache Portable Runtime&#xff0c;Apache可移植运行库&#xff09;和BIO&#xff08;Blocking IO&#xff0c;阻塞IO&#xff09;。以…