Aop+SpringBoot 自定义注解| 8月更文挑战

778 阅读3分钟

这是我参与8月更文挑战的第23天

引言

在很多业务场景中,对一些重复需求、拦截需求一般是通过引入工具类或者拦截器来统一进行处理。但是此方法又存在大量代码冗余、控制粒度太大等弊端。

在Springboot中,我们可以通过Aop+自定义注释更加简洁、高效地解决以上问题.

自定义注解

什么是注解?

Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。Java 语言中的类、方法、变量、参数和包等都可以被标注。

自定义注解实现

最简单的实现,只需在类前加入@interface即标记,此类是一个注解类

@Target(ElementType.METHOD)
@Documented  
@Retention(RetentionPolicy.RUNTIME) 
@Inherited
public @interface UserServerINFO {

}
@Target:说明了Annotation所修饰的对象范围

取值(ElementType)有:

1.CONSTRUCTOR:用于描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD:用于描述方法
5.PACKAGE:用于描述包
6.PARAMETER:用于描述参数
7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

@Documented:用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,没有成员。
@Retention:表示需要在什么级别保存该注释信息,用于描述注解的生命周期

取值(RetentionPoicy)有:

1.SOURCE:在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)
3.RUNTIME:在运行时有效(即运行时保留)

@Inherited:阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

以上即是自定义注解的使用方式,非常简洁。

Aop

基本概念

Aspect: Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。

Joint point: 表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。

Pointcut: 表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。

Advice: Advice 定义了在 pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。

Demo

需求:自定义注解并拦截处理用户请求信息

注解定义
@Target(ElementType.METHOD)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface UserServerINFO {

}
方法使用
@UserServerINFO //作用于方法上
@GetMapping("/Test")
public ResponseResult getTest() {
    return ResponseResult.success();
}
Aop拦截
//标记为一个切面类
@Aspect
//标记为一个组件,交给Spring管理
@Component
public class UserServerAop {
    //定义切点表达式,扫描带有@UserServerINFO注解的所有方法
    @Pointcut("@annotation(com.ycloud.cloudlink.annotation.UserServerINFO)")
    public void pointcut() { }

    //配置环绕通知
    @Around("pointcut()")
    public Object parsingHashids(ProceedingJoinPoint joinPoint) throws Throwable {
        //获取请求信息
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        // 处理业务需求
          
        return joinPoint.proceed();
    }
}

以上,即是自定义注解+Aop使用方法。