java自定义注解实现
自定义注解实现
- 定义注解
- 切面实现注解功能
- 使用注解
定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface NoRepeatSubmit {int lockTime() default 3;TimeUnit timeUint() default TimeUnit.SECONDS;enum TimeUnit {SECONDS, MINUTES}
}
@Retention:元注解,表示在运行时生效
@Target:元注解,标注注解用在类,方法还是字段上
@Documentted:元注解,表示会生成到javadoc中
切面实现注解功能
引入切面依赖,springaop中包含了aspectJ的功能
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>3.0.7</version></dependency>
使用到了redis,增加redis配置依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>3.0.7</version></dependency>
spring:data:redis:database: 0host: x.x.x.xport: 4410password:XXXtimeout: 5000lettuce:pool:max-active: 32max-idle: 16min-idle: 8max-wait: -1
package com.hoitung.fyz.aspect;import cn.hutool.core.date.DateUtil;
import com.hoitung.fyz.annotation.NoRepeatSubmit;
import jakarta.annotation.Resource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;import java.util.Objects;@Component
@Aspect
public class NoRepeatSubmitAspect {@Resourceprivate StringRedisTemplate stringRedisTemplate;@Pointcut(value = "@annotation(noRepeatSubmit)")public void pointCutNoRepeatSubmit(NoRepeatSubmit noRepeatSubmit) {}@Around(value = "pointCutNoRepeatSubmit(noRepeatSubmit)", argNames = "joinPoint,noRepeatSubmit")public Object around(ProceedingJoinPoint joinPoint, NoRepeatSubmit noRepeatSubmit) throws Throwable {String key = "test";int i = noRepeatSubmit.lockTime();String value = stringRedisTemplate.opsForValue().get(key);if(Objects.nonNull(value)) {long oldSec = Long.valueOf(value);long curSec = DateUtil.currentSeconds();if(curSec - oldSec > 1) {return "请勿重复提交";}} else {stringRedisTemplate.opsForValue().set(key, String.valueOf(DateUtil.currentSeconds()));}return joinPoint.proceed();}}
使用注解
@RestController
@RequestMapping("/test")
public class TestController {@NoRepeatSubmit(lockTime = 1)@RequestMapping("/1")public String test() {return "test";}
}
测试结果: