spring aop与自定义注解

175 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

Spring AOP可以帮助我们java在不修改源代码的前提下实现功能增强,其底层实现基于java动态代理或者CGLIB
以往我使用execution选定具体利用AOP扩展哪些类,以及可以模糊匹配......
execution(* com.example.xuexitong.controller..*.*(..))
这样使用很不灵活,因为并不是Service中所有的方法都需要被增强

应用场景

需要灵活用共性需求的地方都可以使用该方案
1、收集上报指定关键方法的入参、执行时间、返回结果等关键信息,用作后期调优
2、关键方法在幂等性前置校验(基于本地消息表)
3、类似于Spring-Retry模块,提供关键方法多次调用重试机制。
4、提供关键方法自定义的快速熔断、服务降级等职责。
5、关键方法的共性入参校验。
6、关键方法在执行后的扩展行为、例如记录日志、启动其他任务等。

首先引入aspectjweaver依赖

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>

新建自定义注解,利用@interface关键字定义注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodExporter {
}

定义切面

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TestAop {
    @Around("@annotation(com.example.xuexitongtwo.aopzhujie.MethodExporter)")
    public Object methodExporter(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("方法执行前动作");

        // 执行目标方法,获取方法返回值
        Object preceed = joinPoint.proceed();
        System.out.println("方法执行后动作");
        return preceed;
    }
}

控制层

import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;
import com.example.xuexitongtwo.aopzhujie.MethodExporter;

@RestController
public class TestConTroller {
    
    @MethodExporter
    @GetMapping("/test2")
    public Integer test2() {
        System.out.println("方法执行");
        return 1;
    }
}

启动项目

写http文件

11.png

运行结果

方法执行前动作
方法执行
方法执行后动作