package com.ys.modules.protocol.custominterface; import java.lang.annotation.*; @Target({ElementType.METHOD})//设置在方法上使用此注解 @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Starter { /** * 默认3秒内算重复提交 */ long timeOut() default 3; }
//实现aop
package com.ys.modules.protocol.aop; import com.ys.modules.protocol.custominterface.Starter; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.net.*; import java.util.concurrent.TimeUnit; @Component @Slf4j @Aspect public class StarterAop { @Autowired private RedisTemplate<String, String> redisTemplate; //切入路径为自定义注解路径. @Pointcut("@annotation(com.ys.modules.protocol.custominterface.Starter)") public void serviceNoRepeat() { System.out.println("这是一个切入点!"); } /** * 此方法是线程安全的 * @param point * @throws Exception */ @Before("serviceNoRepeat()") public synchronized void Before(JoinPoint point) throws Exception { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); Assert.notNull(attributes, "无请求!"); HttpServletRequest request = attributes.getRequest(); Assert.notNull(request, "request can not null"); //获取用户ip String userIp = getIp(request); String requestURI = request.getRequestURI();//请求接口 //这里获取一下用户是否在过期时间内是否请求过相对应的接口! String userUrl = redisTemplate.opsForValue().get(userIp + requestURI); Assert.isNull(userUrl, "重复请求!"); //获取注解内的重复时间 MethodSignature signature = (MethodSignature) point.getSignature(); Assert.notNull(signature, "无法解析注解!"); Method method = signature.getMethod(); Assert.notNull(method, "解析注解错误!"); Starter annotation = method.getAnnotation(Starter.class); Assert.notNull(annotation, "获取注解失败!"); long time = annotation.timeOut(); Assert.isTrue(time > 0, "时间解析失败,请设置正确的过期时间!"); //设置过期时间 条件:用户ip加用户请求接口做限制! redisTemplate.opsForValue().set(userIp + requestURI, requestURI, time, TimeUnit.SECONDS); } public String getIp(HttpServletRequest request) throws UnknownHostException { String remoteAddr = request.getRemoteAddr(); if (StringUtils.hasLength(remoteAddr)) { if (!remoteAddr.equals("0:0:0:0:0:0:0:1")) { return remoteAddr; } } return InetAddress.getLocalHost().getHostAddress(); } }