SpringBoot之自定义注解

1.maven依赖:

<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2.自定义注解:这里做的是一个统计方法执行时间的注解

package com.example.springboot.demo.annotation;

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 ExecutionTime {
}

@Retention :用来说明该注解类的生命周期。它有以下三个参数:
RetentionPolicy.SOURCE : 注解只保留在源文件中
RetentionPolicy.CLASS : 注解保留在class文件中,在加载到JVM虚拟机时丢弃
RetentionPolicy.RUNTIME : 注解保留在程序运行期间,此时可以通过反射获得定义在某个类上的所有注解。

@Target : 用来说明该注解可以被声明在那些元素之前。
ElementType.TYPE:说明该注解只能被声明在一个类前。
ElementType.FIELD:说明该注解只能被声明在一个类的字段前。
ElementType.METHOD:说明该注解只能被声明在一个类的方法前。
ElementType.PARAMETER:说明该注解只能被声明在一个方法参数前。
ElementType.CONSTRUCTOR:说明该注解只能声明在一个类的构造方法前。
ElementType.LOCAL_VARIABLE:说明该注解只能声明在一个局部变量前。
ElementType.ANNOTATION_TYPE:说明该注解只能声明在一个注解类型前。
ElementType.PACKAGE:说明该注解只能声明在一个包名前。

3.定义切面类

package com.example.springboot.demo.annotation;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;


@Aspect
@Component
@Slf4j
public class ExecutionTimeAspect {

    ThreadLocal<Long> beginTime = new ThreadLocal<>();

    @Pointcut("@annotation(com.example.springboot.demo.annotation.ExecutionTime)")
    public void pointcut(){}

    @Before("pointcut()")
    public void doBefore(){
        long start = System.currentTimeMillis();
        beginTime.set(start);
        log.info("======开始执行======:{}",start);
    }


    @After("pointcut()")
    public void doAfter(){
        long over = System.currentTimeMillis();
        log.info("======执行结束======:{}",over);
        log.info("======共耗时======:{}",over - beginTime.get());
    }
}

@Aspect:声明该类为一个注解类;
@Pointcut:定义一个切点,后面跟随一个表达式,表达式可以定义为切某个注解,也可以切某个 package 下的方法;
切点定义好后,就是围绕这个切点做文章了:

@Before: 在切点之前,织入相关代码;
@After: 在切点之后,织入相关代码;
@AfterReturning: 在切点返回内容后,织入相关代码,一般用于对返回值做些加工处理的场景;
@AfterThrowing: 用来处理当织入的代码抛出异常后的逻辑处理;
@Around: 环绕,可以在切入点前后织入代码,并且可以自由的控制何时执行切点;

4.使用

    @GetMapping("/findUser")
    @ExecutionTime
    public List<User> findUser(){
        return userService.findUser();
    }
发布了48 篇原创文章 · 获赞 1 · 访问量 2831

猜你喜欢

转载自blog.csdn.net/Forest24/article/details/99714763