【springboot】使用AOP

1. 添加依赖

<!--        AOP依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2. 创建切面类

1. 创建切面类

      创建一个切面类,并使用 @Aspect 注解标记,并在这个类中定义切点和通知。

@Aspect // 表示这是一个切面
@Component // 托管到spring容器中
public class AccessRecordAspect {
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    // 定义切点 匹配TestController中的test*方法
    @Pointcut("execution(* com.huan.web.controllers.TestController.test*(..))")
    public void a(){}

    // 使用后置增强,在方法正确执行后执行
    @AfterReturning("a()")
    public void record(JoinPoint joinPoint){
        System.out.println("记录访问记录");
        // 获取目标方法参数
        Object[] args = joinPoint.getArgs();
        System.out.println(args[0]);
    }
}

2. 切点表达式

      切点表达式通用模式:execution(修饰符模式? 返回类型模式 包名.类名.方法名(参数模式) 异常模式?)
      其中的 ? 表示该部分是可选的

  • 修饰符模式:可选部分,用于匹配方法的修饰符(如 public、private 等)。例如:public。
  • 返回类型模式:用于匹配方法的返回类型。可以使用通配符 * 表示任意返回类型。例如:*。
  • 包名:用于匹配方法所在的包名。例如:com.example.service。
  • 类名:用于匹配方法所在的类名。可以使用通配符 * 表示任意类。例如:*。
  • 方法名:用于匹配方法名。可以使用通配符 * 表示任意方法。例如:*。
  • 参数模式:用于匹配方法的参数类型。可以使用通配符 … 表示任意数量和类型的参数。例如:(…)。
  • 异常模式:可选部分,用于匹配方法抛出的异常类型。例如:throws IOException。

一些常见的切点表达式示例:

execution:
    用于匹配方法执行。
    语法:execution(修饰符模式? 返回类型模式 包名.类名.方法名(参数模式) 异常模式?)
    示例:execution(* com.example.service.*.*(..)) 匹配 com.example.service 包中的所有类的所有方法。

within:
    用于匹配指定类型内的方法。
    语法:within(type-pattern)
    示例:within(com.example.service..*) 匹配 com.example.service 包及其子包中的所有类。

this:
    用于匹配当前 AOP 代理对象的类型。
    语法:this(type)
    示例:this(com.example.service.UserService) 匹配代理对象是 UserService 类型的所有方法。

target:
    用于匹配目标对象的类型。
    语法:target(type)
    示例:target(com.example.service.UserService) 匹配目标对象是 UserService 类型的所有方法。

args:
    用于匹配方法参数的类型。
    语法:args(argument-type-pattern)
    示例:args(java.lang.String) 匹配所有参数为 String 类型的方法。

@annotation:
    用于匹配方法上具有指定注解的方法。
    语法:@annotation(annotation-type)
    示例:@annotation(org.springframework.transaction.annotation.Transactional) 匹配所有带有 @Transactional 注解的方法。

@within:
    用于匹配具有指定注解的类型内的方法。
    语法:@within(annotation-type)
    示例:@within(org.springframework.stereotype.Service) 匹配所有带有 @Service 注解的类中的方法。

@target:
    用于匹配目标对象类型上具有指定注解的方法。
    语法:@target(annotation-type)
    示例:@target(org.springframework.stereotype.Service) 匹配目标对象类型上带有 @Service 注解的方法。

@args:
    用于匹配运行时传递的参数具有指定注解的方法。
    语法:@args(annotation-type)
    示例:@args(org.springframework.web.bind.annotation.RequestBody) 匹配参数带有 @RequestBody 注解的方法。

3. 增强方法

  • @Before:在目标方法执行前执行。
  • @After:在目标方法执行后执行。
  • @AfterReturning:在目标方法正常返回后执行。
  • @AfterThrowing:在目标方法抛出异常后执行。
  • @Around:环绕增强,可以在目标方法执行前后执行。

      我之前简单测试了下五种增强方法的执行顺序(文章),结论如下:

  • 无异常时  执行顺序为:环绕增强(前)-> 前置增强 -> 目标方法 -> 返回增强 -> 后置增强 -> 环绕增强(后)
  • 有异常时  执行顺序为:环绕增强(前)-> 前置增强 -> 目标方法 -> 异常增强 -> 后置增强 。

3. 开启AOP

      在配置文件中使用@EnableAspectJAutoProxy注解开启AOP功能

在这里插入图片描述

4. 创建控制类

@RestController
@RequestMapping("test")
@Tag(name = "测试",description = "测试springMVC拦截器实现记录访问次数")
public class TestController {
    @GetMapping("getInfo/{id}")
    public String test(@PathVariable Integer id) {
        switch (id){
            case 1:
                return "1";
            case 2:
                return "2";
            default:
                return "3";
        }
    }
}

5. 测试

      在浏览器中输入 http://localhost:8080/test/getInfo/1 测试aop是否生效。
在这里插入图片描述
      console输出,AOP生效。

在这里插入图片描述
      over…
在这里插入图片描述

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用SpringBoot AOP的步骤: 1. 首先,在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> ``` 2. 创建一个切面类,使用@Aspect注解标记该类,并在该类中定义切点和通知。 ```java @Aspect @Component public class MyAspect { @Pointcut("execution(* com.example.demo.service.*.*(..))") public void pointcut() {} @Before("pointcut()") public void before(JoinPoint joinPoint) { System.out.println("Before method: " + joinPoint.getSignature().getName()); } @After("pointcut()") public void after(JoinPoint joinPoint) { System.out.println("After method: " + joinPoint.getSignature().getName()); } } ``` 3. 在应用程序主类上添加@EnableAspectJAutoProxy注解,启用自动代理。 ```java @SpringBootApplication @EnableAspectJAutoProxy public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` 4. 在需要使用AOP的类或方法上添加自定义注解,并在切面类中使用@Around注解来拦截该注解。 ```java @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnotation {} @Around("@annotation(com.example.demo.aspect.MyAnnotation)") public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("Before method: " + joinPoint.getSignature().getName()); Object result = joinPoint.proceed(); System.out.println("After method: " + joinPoint.getSignature().getName()); return result; } @Service public class MyService { @MyAnnotation public void doSomething() { System.out.println("Doing something..."); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

睆小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值