• Spring AOP


    1、AOP 简介

    (1)面向切面编程(方面), 利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得
    业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
    (2)通俗描述:不通过修改源代码方式,在主干功能里面添加新功能

    2、AOP 底层原理(有两种情况动态代理)

    2.1 有接口情况,使用 JDK 动态代理(创建接口实现类代理对象,增强类的方法)

    2.2 没有接口情况,使用 CGLIB 动态代理(创建子类的代理对象,增强类的方法)

    3、AOP术语

    4、Spring 基于 AspectJ 实现 AOP 操作 (推荐基于注解方式实现,也可以基于xml方式实现)

    切入点表达式:

    (1)切入点表达式作用:知道对哪个类里面的哪个方法进行增强
    (2)语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )

    相同的切入点抽取:

    1. @Pointcut(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    2. public void pointdemo() {
    3. }
    4. //前置通知
    5. //@Before 注解表示作为前置通知
    6. @Before(value = "pointdemo()")
    7. public void before() {
    8. System.out.println("before.........");
    9. }

    有多个增强类多同一个方法进行增强,设置增强类优先级;在增强类上面添加注解 @Order(数字类型值),数字类型值越小优先级越高:

    1. @Component
    2. @Aspect
    3. @Order(1)
    4. public class PersonProxy

    完全使用注解开发(Springboot): 创建配置类,不需要创建 xml 配置文件

    1. @Configuration
    2. @ComponentScan(basePackages = {"com.atguigu"})
    3. @EnableAspectJAutoProxy(proxyTargetClass = true)
    4. public class ConfigAop {
    5. }

    4.1 创建类,在类里面定义方法

    1. public class User {
    2. public void add() {
    3. System.out.println("add.......");
    4. }
    5. }

    4.2 创建增强类(代理类)(编写增强逻辑:在增强类里面,创建方法,让不同方法代表不同通知类型)

    1. //增强的类
    2. public class UserProxy {
    3. public void before() {//前置通知
    4. System.out.println("before......");
    5. }
    6. }

    4.3 进行通知的配置

    (1)在 spring 配置文件中,开启注解扫描

    1. <beans xmlns="http://www.springframework.org/schema/beans"
    2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xmlns:context="http://www.springframework.org/schema/context"
    4. xmlns:aop="http://www.springframework.org/schema/aop"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans
    6. http://www.springframework.org/schema/beans/spring-beans.xsd
    7. http://www.springframework.org/schema/context
    8. http://www.springframework.org/schema/context/spring-context.xsd
    9. http://www.springframework.org/schema/aop
    10. http://www.springframework.org/schema/aop/spring-aop.xsd">
    11. <context:component-scan basepackage="com.atguigu.spring5.aopanno">context:component-scan>


    (2)使用注解创建 User 和 UserProxy 对象

    1. //被增强的类
    2. @Component
    3. public class User {}
    4. //增强的类
    5. @Component
    6. public class UserProxy {}

    (3)在增强类上面添加注解 @Aspect

    1. @Component
    2. @Aspect //生成代理对象
    3. public class UserProxy {}


    (4)在 spring 配置文件中开启生成代理对象

    1. <aop:aspectj-autoproxy>aop:aspectj-autoproxy>

    4.4 配置不同类型的通知(在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置)

    1. //增强的类
    2. @Component
    3. @Aspect //生成代理对象
    4. public class UserProxy {
    5. //前置通知
    6. //@Before 注解表示作为前置通知
    7. @Before(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    8. public void before() {
    9. System.out.println("before.........");
    10. }
    11. //后置通知(返回通知)
    12. @AfterReturning(value = "execution(*
    13. com.atguigu.spring5.aopanno.User.add(..))")
    14. public void afterReturning() {
    15. System.out.println("afterReturning.........");
    16. }
    17. //最终通知
    18. @After(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    19. public void after() {
    20. System.out.println("after.........");
    21. }
    22. //异常通知
    23. @AfterThrowing(value = "execution(*
    24. com.atguigu.spring5.aopanno.User.add(..))")
    25. public void afterThrowing() {
    26. System.out.println("afterThrowing.........");
    27. }
    28. //环绕通知
    29. @Around(value = "execution(* com.atguigu.spring5.aopanno.User.add(..))")
    30. public void around(ProceedingJoinPoint proceedingJoinPoint) throws
    31. Throwable {
    32. System.out.println("环绕之前.........");
    33. //被增强的方法执行
    34. proceedingJoinPoint.proceed();
    35. System.out.println("环绕之后.........");
    36. }
    37. }

  • 相关阅读:
    连PostgreSQL问题:expected authentication request from server, but received v
    【Leetcode】136.只出现一次的数字
    真“火爆”还是假“繁荣” 用数据观察Art Gobblers
    Java 中“1000==1000”为false,而”100==100“为true?
    盘点一个Python面向对象的基础问题
    60+开源数据集资源大合集(医学图像、卫星图像、语义分割、自动驾驶、图像分类等)
    mysql常用基础命令
    Python打包成exe,文件太大问题解决办法
    02 nginx 中几种 location 表达式的优先级问题
    在Jetson Xavier NX 开发板上使用VScode执行ROS程序详细过程
  • 原文地址:https://blog.csdn.net/xd592319702/article/details/126131697