+-
Spring5学习——4、AOP概念

1.什么是AOP
面向切面编程

AOP底层使用动态代理
(1)有接口情况 【使用JDK动态代理】

创建代理对象
要想创建一个代理对象,需要使用Proxy类的newProxyInstance方法。这个方法有三个参数:

一个类加载器(class loader)。 一个Class对象数组,每个元素都是需要实现的接口。 一个调用处理器

(2)无接口情况 【使用CGLIB动态代理】

AOP术语
(1)连接点:可以被增强的方法就是连接点
(2)切入点:实际被增强的方法就是切入点
(3)通知【增强】:实际增强方法中增强的部分

  - 前置通知
  - 后置通知
  - 环绕通知
  - 异常通知
  - 最终通知

(4)切面:

使用AspectJ进行AOP操作
execution(权限修饰符 返回类型 类全路径 方法名称(参数列表))

(1)创建类

@Component
public class User {

    public void add(){
        System.out.println("add...");
    }
    
}

(2)创建增强类

@Component
@Aspect
public class UserProxy {

    //前置通知
    @Before(value = "execution(* com.example.demo.entity.User.add())")
    public void before(){
        System.out.println("before...");
    }

    //最终通知[有没有异常都会执行]
    @After(value = "execution(* com.example.demo.entity.User.add())")
    public void after(){
        System.out.println("after...");
    }

    //后置通知
    @AfterReturning(value = "execution(* com.example.demo.entity.User.add())")
    public void afterReturing(){
        System.out.println("afterReturning...");
    }

    //异常通知
    @AfterThrowing(value = "execution(* com.example.demo.entity.User.add())")
    public void afterThrowing(){
        System.out.println("afterThrowing...");
    }

    //环绕通知
    @Around(value = "execution(* com.example.demo.entity.User.add())")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("around before...");
        proceedingJoinPoint.proceed();
        System.out.println("around after...");
    }

}

(3)进行通知的配置

 1. 在Spring配置文件中,开启注解开发
 2. 使用注解创建User和UserProxy对象
 3. 在增强类上面添加注解@Aspect
 4. 在Spring配置文件中开启生成代理对象

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

       <!--开启注解扫描-->
       <context:component-scan base-package="com.example.demo.entity"></context:component-scan>

       <!--开启Aspect生成代理对象-->
       <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

(4)公共切入点抽取

    @Pointcut(value = "execution(* com.example.demo.entity.User.add())")
    public void point(){
    }

    //前置通知
    @Before(value = "point()")
    public void before(){
        System.out.println("before...");
    }

(5)增强类优先级【多个增强类对同一方法进行增强】

 增强类上添加注解@Order(数字类型值),数字值越小优先级越高