要使用@Idempotent注解,你需要先在你的项目中引入Redisson的依赖。然后,你需要定义一个拦截器,用于拦截需要进行幂等性检查的接口。在该拦截器中,你需要获取当前请求所对应的方法,并判断该方法是否被@Idempotent注解所标记。如果是,则需要从请求头中获取token,并将其作为key,获取一个RLock对象。如果该RLock对象已经被其他请求锁定,则当前请求会抛出异常;否则,当前请求会获得该RLock对象并执行后续操作。当请求处理完成后,我们需要释放该RLock对象。
1.定义@Idempotent注解:
在你的项目中引入Redisson的依赖。
定义一个注解@Idempotent,用于标记需要进行幂等性检查的接口。
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Idempotent {
String value() default "";
}
2. 定义拦截器
定义一个拦截器IdempotentInterceptor,用于拦截需要进行幂等性检查的接口。
@Component
public class IdempotentInterceptor extends HandlerInterceptorAdapter {
@Autowired
private RedissonClient redissonClient;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Method method = ((HandlerMethod) handler).getMethod();
Idempotent idempotent = method.getAnnotation(Idempotent.class);
if (idempotent == null) {
return true;
}
String token = request.getHeader("token");
String key = "idempotent:" + token;
RLock lock = redissonClient.getLock(key);
boolean res = false;
try {
res = lock.tryLock(0, 10, TimeUnit.SECONDS);
if (res) {
return true;
} else {
throw new RuntimeException("请勿重复提交");
}
} finally {
if (res) {
lock.unlock();
}
}
}
}
3. 注入拦截器
这一步把你开发好的拦截器注入容器使其生效
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private IdempotentInterceptor idempotentInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(idempotentInterceptor).addPathPatterns("/**");
}
}
4.使用自定义注解
在需要进行幂等性检查的接口上添加@Idempotent注解。
@RestController
public class TestController {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@PostMapping("/test")
@Idempotent
public String test(@RequestBody Map<String, Object> params) {
// your code here
}
}