JAVA利用自定义本地锁解决重复提交的问题

JAVA利用自定义本地锁解决重复提交的问题

引入jar包

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>

自定义本地锁

“`
package com.hzt.listener;
import java.lang.annotation.*;

/**
* 自定义-控制重复提交锁
*/
@Target(ElementType.METHOD) //作用于方法
@Retention(RetentionPolicy.RUNTIME) //运行时有效
@Documented
@Inherited
public @interface LocalLock {
String key() default “”;
}
“`

自定义注解切面 (aop拦截器实现)
“`
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;

/**
* @Desc: 自定义注解拦截器
* @Author: zmk
* @Date: 2022/4/2
*/
@Aspect
@Configuration
public class LockMethodInterceptor {
private final Logger log = LoggerFactory.getLogger(LockMethodInterceptor.class);

private static final Cache<String, Object> CACHES = CacheBuilder.newBuilder()
//最大缓存数
.maximumSize(1000)
//设置过期时间
.expireAfterWrite(3, TimeUnit.SECONDS)
.build();

@Around(value = “@annotation(localLock)”)
public Object interceptor (ProceedingJoinPoint point, LocalLock localLock) {

//localLock.key() 这个是获取controller的key属性, point.getArgs()获取key的值
String key = getKey(localLock.key(), point.getArgs());
if (StringUtils.isNotBlank(key)) {
if (CACHES.getIfPresent(key) != null) {
throw new RuntimeException(“请勿重复提交”);
}
//如果是第一次请求, 将key放入缓存
CACHES.put(key, key);
}

try {
return point.proceed();
} catch (Throwable throwable) {
throw new RuntimeException(“服务器异常”);
} finally {
//标记为无效
// CACHES.invalidate(key);
}

}

/**
*
* key 生成策略
* @param key key表达式
* @param args 参数
* @return 生成的key
*/
private String getKey(String key, Object[] args) {
for (int i = 0; i < args.length; i++) {
key = key.replace(“arg[” + i + “]”, args[i].toString());
}
return key;
}
“`

定义controller接口

“`
@GetMapping(“/query”)
@LocalLock(key = “param:arg[0]”)
public String query (@RequestParam(“abc”) String abc) {
return “ok”;
}
“`

您可能还喜欢...

发表评论

邮箱地址不会被公开。