1:配置pom文件
org.springframework.boot
spring-boot-starter-data-redis
redis.clients
jedis
3.0.1
2:配置redis链接,application.yml
redis:
host: 192.168.0.70
port: 6379
password:
database: 13
timeout: 6000
3:添加JedisPool配置类
package com.sword.storageproduce.redis;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@EnableCaching
public class RedisCacheConfiguration extends CachingConfigurerSupport {
public static final Logger logger = LoggerFactory.getLogger(RedisCacheConfiguration.class);
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.database}")
private int database;
@Bean
public JedisPool redisPoolFactory() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, null,database);
return jedisPool;
}
}
4:添加redis处理类
package com.sword.storageproduce.redis;
public interface JedisClient {
String set(String key, String value);
String get(String key);
Boolean exists(String key);
Long expire(String key, int seconds);
Long ttl(String key);
Long incr(String key);
Long hset(String key, String field, String value);
String hget(String key, String field);
Long hdel(String key, String... field);
}
package com.sword.storageproduce.redis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
@Component
public class JedisClientPool implements JedisClient {
@Autowired
private RedisCacheConfiguration configuration;
@Override
public String set(String key, String value) {
Jedis jedis = configuration.redisPoolFactory().getResource();
String result = jedis.set(key, value);
jedis.close();
return result;
}
@Override
public String get(String key) {
Jedis jedis = configuration.redisPoolFactory().getResource();
String result = jedis.get(key);
jedis.close();
return result;
}
@Override
public Boolean exists(String key) {
Jedis jedis = configuration.redisPoolFactory().getResource();
Boolean result = jedis.exists(key);
jedis.close();
return result;
}
@Override
public Long expire(String key, int seconds) {
Jedis jedis = configuration.redisPoolFactory().getResource();
Long result = jedis.expire(key, seconds);
jedis.close();
return result;
}
@Override
public Long ttl(String key) {
Jedis jedis = configuration.redisPoolFactory().getResource();
Long result = jedis.ttl(key);
jedis.close();
return result;
}
@Override
public Long incr(String key) {
Jedis jedis = configuration.redisPoolFactory().getResource();
Long result = jedis.incr(key);
jedis.close();
return result;
}
@Override
public Long hset(String key, String field, String value) {
Jedis jedis = configuration.redisPoolFactory().getResource();
Long result = jedis.hset(key, field, value);
jedis.close();
return result;
}
@Override
public String hget(String key, String field) {
Jedis jedis = configuration.redisPoolFactory().getResource();
String result = jedis.hget(key, field);
jedis.close();
return result;
}
@Override
public Long hdel(String key, String... field) {
Jedis jedis = configuration.redisPoolFactory().getResource();
Long result = jedis.hdel(key, field);
jedis.close();
return result;
}
}
5:添加注解类,并且定义默认访问次数,有效时间,在这里直接修改时间就可以。
package com.sword.storageproduce.common.interfices;
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface LimitUserRequest {
int limitCounts() default 1;
int timeSecond() default 60;
}
6:添加切点
package com.sword.storageproduce.common.aop;
import com.sword.storageproduce.common.exceptions.LimitUserRequestException;
import com.sword.storageproduce.common.interfices.LimitUserRequest;
import com.sword.storageproduce.redis.JedisClient;
import com.sword.storageproduce.util.UserHelper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.util.concurrent.TimeUnit;
@Aspect
@Component
public class LimitUserRequestDisplay {
public static final Logger logger = LoggerFactory.getLogger(LimitUserRequestDisplay.class);
@Autowired
private JedisClient jedis;
@Autowired
private RedisTemplate redisTemplate;
@Pointcut("@annotation(com.sword.storageproduce.common.interfices.LimitUserRequest)")
public void before(){
logger.info("进入切面工程");
}
@Before("before()")
public void requestLimit(JoinPoint joinPoint) throws LimitUserRequestException {
logger.info("开始切面操作");
try {
// 获取HttpRequest
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
logger.info("url={}", request.getRequestURI());
HttpServletResponse response = attributes.getResponse();
// 判断request不能为空
if (request == null) {
throw new LimitUserRequestException("HttpServletRequest有误...");
}
LimitUserRequest limit = this.getAnnotation(joinPoint);
if(limit == null) {
return;
}
String userId = UserHelper.getLoginUserId();
String uri = request.getRequestURI().toString();
String redisKey = "limit-user-request:" + uri + ":" + userId;
// 设置在redis中的缓存,累加1
long count = jedis.incr(redisKey);
// 如果该key不存在,则从0开始计算,并且当count为1的时候,设置过期时间
if (count == 1) {
jedis.expire(redisKey, limit.timeSecond());
redisTemplate.expire(redisKey, limit.timeSecond(), TimeUnit.MILLISECONDS);
}
// 如果redis中的count大于限制的次数,则报错
if (count > limit.limitCounts()) {
InetAddress address = InetAddress.getLocalHost();
logger.info("用户IP[" + address.getHostAddress() + "]访问地址[" + uri + "]超过了限定的次数[" + limit.limitCounts() + "]");
throw new LimitUserRequestException("当前用户重复访问");
}
} catch (LimitUserRequestException e) {
throw e;
} catch (Exception e) {
e.printStackTrace();
}
}
private LimitUserRequest getAnnotation(JoinPoint joinPoint) throws Exception {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
Method method = methodSignature.getMethod();
if (method != null) {
return method.getAnnotation(LimitUserRequest.class);
}
return null;
}
}
7:测试
@LimitUserRequest
@GetMapping(value = "/testChange")
public String user(@RequestParam Map param) {
return "成功调用接口";
}



