高并发秒杀——SpringBoot集成redis
shop--13.升级--Redis缓存技术
集成Redis
1.添加Jedis依赖
2.添加Fastjson依赖
1.安装redis http://www.runoob.com/redis/redis-install.html
1.引入redis依赖
<!--redis客户端:jedis--> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.1.41</version> </dependency> <!--配置springBootConfiguration, 可以使用@ConfigurationProperties(prefix = "redis")--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
2.在application.properties加入redis配置文件
redis.host=127.0.0.1 redis.port=6379 redis.timeout=3 redis.pool.MaxTotal=10 redis.database=0 redis.pool.maxActive=100 redis.pool.maxIdle=20 redis.pool.maxWait=3 redis.pool.testOnBorrow=true
3. 定义redis的类,引入redis配置
@Component @ConfigurationProperties(prefix = "redis") public class RedisConfig { private String host; private int port; private int timeout; private int poolMaxTotal; private int poolMaxIdle; private int poolMaxWait; public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public int getTimeout() { return timeout; } public void setTimeout(int timeout) { this.timeout = timeout; } public int getPoolMaxTotal() { return poolMaxTotal; } public void setPoolMaxTotal(int poolMaxTotal) { this.poolMaxTotal = poolMaxTotal; } public int getPoolMaxIdle() { return poolMaxIdle; } public void setPoolMaxIdle(int poolMaxIdle) { this.poolMaxIdle = poolMaxIdle; } public int getPoolMaxWait() { return poolMaxWait; } public void setPoolMaxWait(int poolMaxWait) { this.poolMaxWait = poolMaxWait; } }
4.RedisPoolFactory类
@Service public class RedisPoolFactory { @Autowired RedisConfig redisConfig; @Bean public JedisPool JedisPoolFactory(){ JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxIdle(redisConfig.getPoolMaxIdle()); jedisPoolConfig.setMaxTotal(redisConfig.getPoolMaxTotal()); jedisPoolConfig.setMaxWaitMillis(redisConfig.getPoolMaxWait() * 1000); JedisPool jedisPool = new JedisPool(jedisPoolConfig, redisConfig.getHost(), redisConfig.getPort(), redisConfig.getTimeout() * 1000); return jedisPool; } }
5.编写RedisService类
@Service public class RedisRervice { @Autowired JedisPool jedisPool; /** * h获取单个对象 * @param prefix * @param key * @param clazz * @param <T> * @return */ public <T> T get(KeyPrefix prefix, String key, Class<T> clazz){ Jedis jedis = null; try{ jedis = jedisPool.getResource(); //生成真正的key String realKey = prefix.getKeyPrefix() + key; String str = jedis.get(realKey); T t = stringToBean(str, clazz); return t; }finally { jedis.close(); } } /** * 设置缓存值 * @param prefix * @param key * @param value * @param <T> * @return */ public <T> boolean set(KeyPrefix prefix, String key, T value){ Jedis jedis = null; try{ jedis = jedisPool.getResource(); String str = beanToString(value); if(str == null || str.length() <= 0){ return false; } //生成真正的key String realKey = prefix.getKeyPrefix() + key; int second = prefix.expireSeconds(); if(second <= 0){ jedis.set(realKey, str); }else{ jedis.setex(realKey, second, str); } jedis.set(realKey, str); return true; } finally { jedis.close(); } } private <T> String beanToString(T value) { if(value == null){ return null; } Class<?> clazz = value.getClass(); if(clazz == int.class || clazz == Integer.class){ return "" + value; }else if(clazz == String.class){ return (String) value; } else if(clazz == long.class || clazz == Long.class){ return "" + value; }else{ return JSON.toJSONString(value); } } private <T> T stringToBean(String str, Class<T> clazz) { if (str == null || str.length() <= 0 || clazz == null) { return null; } if (clazz == int.class || clazz == Integer.class) { return (T) Integer.valueOf(str); } else if (clazz == String.class) { return (T) str; } else if (clazz == long.class || clazz == Long.class) { return (T) Long.valueOf(str); } else { return JSON.toJavaObject(JSON.parseObject(str), clazz); } } /** * 判断是否存在 * @param prefix * @param key * @param <T> * @return */ public <T> boolean exits(KeyPrefix prefix, String key){ Jedis jedis = null; try{ jedis = jedisPool.getResource(); String realKey = prefix.getKeyPrefix() + key; return jedis.exists(realKey); } finally { jedis.close(); } } /** * 增加值 * @param prefix * @param key * @param <T> * @return */ public <T> Long incr(KeyPrefix prefix, String key){ Jedis jedis = null; try{ jedis = jedisPool.getResource(); String realKey = prefix.getKeyPrefix() + key; return jedis.incr(realKey); } finally { jedis.close(); } } /** * 减少值 * @param prefix * @param key * @param <T> * @return */ public <T> Long decr(KeyPrefix prefix, String key){ Jedis jedis = null; try{ jedis = jedisPool.getResource(); String realKey = prefix.getKeyPrefix() + key; return jedis.decr(realKey); } finally { jedis.close(); } } }
6.controller中测试
@Autowired RedisService redisService; @RequestMapping(value = "/redis/set", method = RequestMethod.GET) @ResponseBody public boolean redisSet(){ boolean value = redisService.set("key2", "redis"); return value; } @RequestMapping(value = "/redis/get", method = RequestMethod.GET) @ResponseBody public Object redisGet(){ String l = redisService.get("key2", String.class); return l; }
使用一个前缀来区分key
public interface KeyPrefix { int expireSeconds(); String getKeyPrefix(); }
KeyPrefix
public abstract class BasePrefix implements KeyPrefix { private int expireSeconds; private String keyPrefix; public BasePrefix(String keyPrefix) { this(0, keyPrefix); } public BasePrefix(int expireSeconds, String keyPrefix) { this.expireSeconds = expireSeconds; this.keyPrefix = keyPrefix; } //默认 0 代表永不过期 @Override public int expireSeconds() { return expireSeconds; } //不同的类对应不同的prefix @Override public String getKeyPrefix() { String className = getClass().getSimpleName(); return className + ": " + keyPrefix; } }