From ab106e3928584c0ea95a2a36c114485db9334edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=A6=E8=8B=B1=E6=9D=B0?= <327782001@qq.com> Date: Tue, 29 Aug 2023 15:04:24 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E6=B7=BB=E5=8A=A0=E5=88=86=E5=B8=83?= =?UTF-8?q?=E5=BC=8F=E9=94=81,=E5=B9=B6=E7=94=A8paifox=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../springbootkwan/annotation/RedisLock.java | 26 ++++++++ .../springbootkwan/aop/RedisLockAspect.java | 62 +++++++++++++++++++ .../controller/ChatbotController.java | 5 +- .../controller/DepartmentController.java | 11 +++- .../springbootkwan/filter/TimeFilter.java | 1 - 5 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/kwan/springbootkwan/annotation/RedisLock.java create mode 100644 src/main/java/com/kwan/springbootkwan/aop/RedisLockAspect.java diff --git a/src/main/java/com/kwan/springbootkwan/annotation/RedisLock.java b/src/main/java/com/kwan/springbootkwan/annotation/RedisLock.java new file mode 100644 index 0000000..fcc7892 --- /dev/null +++ b/src/main/java/com/kwan/springbootkwan/annotation/RedisLock.java @@ -0,0 +1,26 @@ +package com.kwan.springbootkwan.annotation; + +import org.springframework.core.annotation.AliasFor; +import org.springframework.stereotype.Component; + +import java.lang.annotation.*; + +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Component +public @interface RedisLock { + String value() default ""; + + @AliasFor("key") + String name() default ""; + + @AliasFor("name") + String key() default ""; + + long expire() default 30000; // 默认锁的过期时间,单位毫秒 + + long timeout() default 0; // 默认获取锁的超时时间,单位毫秒 + + boolean fair() default false; // 是否使用公平锁 +} diff --git a/src/main/java/com/kwan/springbootkwan/aop/RedisLockAspect.java b/src/main/java/com/kwan/springbootkwan/aop/RedisLockAspect.java new file mode 100644 index 0000000..13c9017 --- /dev/null +++ b/src/main/java/com/kwan/springbootkwan/aop/RedisLockAspect.java @@ -0,0 +1,62 @@ +package com.kwan.springbootkwan.aop; + +import com.kwan.springbootkwan.annotation.RedisLock; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.core.annotation.Order; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + + +@Aspect +@Component +@Order(1) // 设置切面优先级 +public class RedisLockAspect { + + private final StringRedisTemplate redisTemplate; + + public RedisLockAspect(StringRedisTemplate redisTemplate) { + this.redisTemplate = redisTemplate; + } + + @Around("@annotation(redisLock)") + public Object doWithLock(ProceedingJoinPoint joinPoint, RedisLock redisLock) throws Throwable { + String lockKey = getLockKey(redisLock); + Lock lock = new ReentrantLock(redisLock.fair()); + boolean locked = false; + + try { + locked = lock.tryLock(redisLock.timeout(), TimeUnit.MILLISECONDS); + if (locked) { + if (StringUtils.hasText(lockKey)) { + redisTemplate.opsForValue().set(lockKey, "locked", redisLock.expire(), TimeUnit.MILLISECONDS); + } + return joinPoint.proceed(); + } else { + throw new RuntimeException("Failed to acquire lock."); + } + } finally { + if (locked) { + lock.unlock(); + if (StringUtils.hasText(lockKey)) { + redisTemplate.delete(lockKey); + } + } + } + } + + private String getLockKey(RedisLock redisLock) { + String lockKey = redisLock.key(); + if (!StringUtils.hasText(lockKey)) { + lockKey = redisLock.name(); + } + return lockKey; + } +} + diff --git a/src/main/java/com/kwan/springbootkwan/controller/ChatbotController.java b/src/main/java/com/kwan/springbootkwan/controller/ChatbotController.java index 76e0e70..eb45b42 100644 --- a/src/main/java/com/kwan/springbootkwan/controller/ChatbotController.java +++ b/src/main/java/com/kwan/springbootkwan/controller/ChatbotController.java @@ -8,7 +8,6 @@ import com.kwan.springbootkwan.entity.Result; import com.kwan.springbootkwan.entity.dto.ChatbotDTO; import com.kwan.springbootkwan.service.ChatbotService; import org.apache.commons.lang3.StringUtils; -import org.springframework.cache.annotation.Cacheable; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -57,11 +56,11 @@ public class ChatbotController { /** - * 分页查询所有数据 + * 分页查询所有数据,本地缓存的使用 * * @return 所有数据 */ - @Cacheable("chatbot-cache") +// @Cacheable("chatbot-cache") @GetMapping("/page") public Result selectAll(@RequestParam Integer page , @RequestParam Integer pageSize diff --git a/src/main/java/com/kwan/springbootkwan/controller/DepartmentController.java b/src/main/java/com/kwan/springbootkwan/controller/DepartmentController.java index e718492..77773aa 100644 --- a/src/main/java/com/kwan/springbootkwan/controller/DepartmentController.java +++ b/src/main/java/com/kwan/springbootkwan/controller/DepartmentController.java @@ -1,11 +1,18 @@ package com.kwan.springbootkwan.controller; +import com.kwan.springbootkwan.annotation.RedisLock; import com.kwan.springbootkwan.entity.Department; import com.kwan.springbootkwan.service.DepartmentService; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.List; @@ -63,6 +70,8 @@ public class DepartmentController { @GetMapping("/all") + @RedisLock(key = "myLock_queryTreeAll", expire = 5000, timeout = 3000) +// @RedisLock(key = "myLock_queryTreeAll", timeout = 10000) public ResponseEntity> queryTreeAll() { return ResponseEntity.ok(this.departmentService.queryTreeAll()); } diff --git a/src/main/java/com/kwan/springbootkwan/filter/TimeFilter.java b/src/main/java/com/kwan/springbootkwan/filter/TimeFilter.java index 98dff4a..f3844d9 100644 --- a/src/main/java/com/kwan/springbootkwan/filter/TimeFilter.java +++ b/src/main/java/com/kwan/springbootkwan/filter/TimeFilter.java @@ -18,7 +18,6 @@ public class TimeFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { -// log.info("先执行:接口执行时间"); chain.doFilter(request, response); } } -- GitLab