spring 框架 aop 操作

47 阅读4分钟

// spring 框架 aop 操作 (准备工作)

// 1. 一般基于 AspectJ 实现 AOP操作

// 什么是 AspectJ?

// AspectJ 不是Spring 组成部分 独立的AOP框架 , 一般把 AspectJ 和 Spring 框架一起用 进行AOP 操作

    //2. 基于 AspectJ 实现AOP操作
    // 1) 基于xml 配置文件实现
    // 2) 基于注解方式实现 一般使用这个

    // 3. 在项目工程里面 引入 AOP相关依赖
    //   引入spring-aspects-5.2.6.RELEASE.jar 依赖
    //  引入 AspectJ 相关依赖


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

举例1 :对com.spring.json.User 类里面add方法增强

// * 表示 所有权限修饰符 都可以

// 返回类型 可以省略不写 虽然可以省略不写 但是 也要打个空格 表示分割

// 类全路径

// 方法名

// … 表示 参数列表

//execution(* com.spring.json.User.add(…))

举例2 :对com.spring.json.User 类里面所有方法增强

// * 在第一位表示 所有权限修饰符 都可以

// 返回类型 可以省略不写 虽然可以省略不写 但是 也要打个空格 表示分割

// 类全路径

// * 在第四位表示 类里面所有方法都增强

// … 表示 参数列表

//execution(* com.spring.json.User.*(…))

举例3 :对com.spring.json 这个包里面所有的类里面的方法都增强

// * 在第一位表示 所有权限修饰符 都可以

// 返回类型 可以省略不写 虽然可以省略不写 但是 也要打个空格 表示分割

// * 在第三位表示 包里的所有类

// * 在第四位表示 类里面所有方法都增强

// … 表示 参数列表

1.png

    // 下面就可以 分别用 注解方式 和配置文件方式 对aop进行操作
    // 其实要做的就是 通知(AOP术语)里面的五种类型 进行一个配置 使用

AOP 操作 基于(AspectJ注解)

    //1. 定义个类  在类里定义方法 增强这个类的方法
package com.spring.json.aopSpring;

import org.springframework.stereotype.Component;

/**
 * @User: Json
 * @Date: 2022/3/14
 **/
//被增强类
@Component
public class User {

    public void  add(){
       // int i=10/0;  创建一个异常 模拟 异常通知
        System.out.println("add....");
    }
}

    //2. 创建一个增强类 (编写增强的逻辑)
    // 在增强类里面 创建 方法 让不同的方法 代表不同的通知类型
package com.spring.json.aopSpring;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @User: Json
 * @Date: 2022/3/14
 **/
//增强类
@Component
@Aspect  //生成代理对象
public class UserProxy {


    //
    execution([权限修饰符][返回类型][类全路径][方法名称]([参数列表]))
    // * 表示 所有权限修饰符 都可以
    // 返回类型 可以省略不写  虽然可以省略不写 但是 也要打个空格 表示分割
    // 类全路径
    // 方法名
    // .. 表示 参数列表
    //前置通知 value 可省略
    @Before(value = "execution(* com.spring.json.aopSpring.User.add(..))")
    public void  before(){
        System.out.println("before...前置通知");
    }

    //后置通知 或者(返回通知) 在返回值之后 执行 有异常不会通知
    @AfterReturning("execution(* com.spring.json.aopSpring.User.add(..))")
    public void  afterReturning(){
        System.out.println("AfterReturning...后置通知 返回值之后 执行");
    }

    //最终通知 有异常也会执行
    @After("execution(* com.spring.json.aopSpring.User.add(..))")
    public void  after(){
        System.out.println("after...最终通知");
    }



    //异常通知 如果这个通知执行了   Around 环绕之后 和 AfterReturning() 后置通知 不会执行
    @AfterThrowing("execution(* com.spring.json.aopSpring.User.add(..))")
    public void  afterThrowing(){
        System.out.println("afterThrowing...异常通知");
    }


    //环绕通知 在方法之前 和 方法之后都通知
    @Around("execution(* com.spring.json.aopSpring.User.add(..))")
    public void  around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("around...环绕之前");
        proceedingJoinPoint.proceed();
        System.out.println("around...环绕之后"); // 有异常不会通知
    }

}

    //3. 进行通知的配置 创建coonfig配置文件 或者 xml 配置文件都行
    //3.1 在spring配置文件中 开启注解扫描
    //3.2 使用注解创建 增强对象和被增强对象
    //3.3 在增强类上面增加注解 @Aspect
    //3.4 在spring 配置文件中开启生成代理对象
package com.spring.json.aopSpring.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

/**
 * @User: Json
 * @Date: 2022/3/14
 **/
@Configuration   //把当前类作为 配置类 替代xml配置文件
@ComponentScan(basePackages = {"com.spring.json.aopSpring"})
//@ComponentScan 代替得就是 xml配置文件中
// <context:component-scan base-package="com.spring.json.aopSpring" ></context:component-scan>
//标签
@EnableAspectJAutoProxy //开启 Aspect 生成代理对象
//代替的就是     <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 这个标签
public class ConfigAop {
}

    //4. 配置不同类型的通知
    //4.1 在增强类里面 在作为通知方法上添加通知类型注解 使用切入点表达式配置

具体代码 请查看上面的 标题 2. 创建一个增强类 已经全部编写完成

  1. 相同切入点 抽取 可以把相同切入点 提取出来 封装 一下

2.png

  1. 有多个增强类 对同一个方法进行增强 设置增强优先级

// 在增强类上添加 @order(数字类型值) 数字类型越小 优先级越高

3.png //AOP 操作 基于(AspectJ配置文件)