springboot自定义注解

springboot自定义注解常见的应用就是在自定义记录操作日志、自定义数据字典等操作上面。自定义注解一般是搭配aop使用的。要学习自定义注解
创建注解

@Target(ElementType.METHOD) //注解放置的目标位置,METHOD是可注解在方法级别上
@Retention(RetentionPolicy.RUNTIME) //注解在哪个阶段执行
@Documented //生成文档
public @interface OpreatorLog {
    /**
     * 日志描述,没有默认值,使用注解的时候必须给operateDec参数赋值
     */
    String operateDec();
    /**
     * 日志类型,默认值为2
     * 1:登录日志;2:操作日志;3:定时任务;
     */
    int logType() default 2;
}
  • 注解定义为@interface, 所有的注解会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口
  • 参数成员只能用public或默认(default)这两个访问权修饰
  • 参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组
  • @Target注解:指明了修饰的这个注解的使用范围,也就是注解可以用在哪里。ElementType的取值包含以下几种
  • TYPE:类,接口或者枚举
  • FIELD:域,包含枚举常量
  • METHOD:方法(我们用这个
  • PARAMETER:参数
  • CONSTRUCTOR:构造方法
  • LOCAL_VARIABLE:局部变量
  • ANNOTATION_TYPE:注解类型
  • PACKAGE:包
  • @Retention注解:指明修饰的注解的生存周期,注解在哪个阶段执行。RetentionPolicy的取值包含以下三种
  • SOURCE:源码级别保留,编译后即丢弃。
  • CLASS: 编译级别保留,编译后的class文件中存在,在jvm运行时丢弃,这是默认值。
  • RUNTIME: 运行级别保留,编译后的class文件中存在,在jvm运行时保留,可以被反射调用。(我们用这个
  • @Documented:它代表着此注解会被javadoc工具提取成文档
  • 注解里面可以有多个成员变量,可以通过default给成员变量一个默认值,如果没有默认值,那么在使用该注解的时候必须给这个成员变量赋值

创建切面

创建OperatorLogAspect,代码如下

@Aspect
@Component
public class OperatorLogAspect {
    /**
     * 定义切点Pointcut
     */
    @Pointcut("execution(public * com.moyundong..*.*Controller.*(..))")
    public void excudeService() {

    }

    /**
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("excudeService()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        //从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取切入点所在的方法
        Method method = signature.getMethod();
        //获取操作,如果有注解,就执行增加日志操作
        OpreatorLog myLog = method.getAnnotation(OpreatorLog.class);
        if (myLog != null) {
            //操作类型
            int logType = myLog.logType();
            String operateDec = myLog.operateDec();
            //获取请求的类名
            String className = joinPoint.getTarget().getClass().getName();
            //获取请求的方法名
            String methodName = method.getName();
            System.out.println("logType="+logType);
            System.out.println("operateDec="+operateDec);
            System.out.println("className="+className);
            System.out.println("methodName="+methodName);
            // ......
            // 做你想做的任何事情
        }
        return joinPoint.proceed();
    }
}

使用自定义注解

我们创建一个测试类,在类的方法上面加自定义注解@OpreatorLog,因为operateDec没有默认值,所以必须赋值。logType有默认值,所以可以不输入。

/**
 * @Description: 测试类
 **/
@RestController
@RequestMapping("test")
public class TestController {
    @RequestMapping("add")
    @OpreatorLog(operateDec = "这是一个添加任务")
    public String add(){
        return "添加成功 !";
    }

    @RequestMapping("edit")
    @OpreatorLog(operateDec = "这是一个修改任务")
    public String edit(){
        return "修改成功 !";
    }

    @RequestMapping("delete")
    @OpreatorLog(operateDec = "这是一个删除任务")
    public String delete(){
        return "删除成功 !";
    }

    @RequestMapping("login")
    @OpreatorLog(operateDec = "这是一个登录任务",logType = 1)
    public String login(){
        return "登录成功 !";
    }
}

测试

项目启动后,在浏览器输入http://localhost:8088/moyundong/test/loginhttp://localhost:8088/moyundong/test/add 会得到如下信息

logType=1
operateDec=这是一个登录任务
className=com.moyundong.controller.TestController
methodName=login
logType=2
operateDec=这是一个添加任务
className=com.moyundong.controller.TestController
methodName=add

::: tip 提示
本节内容只是讲了自定义注解的基本原理,后面我们会讲解springboot基于注解的操作日志
:::