SpringBoot整合Redis
1.创建一个SpringBoot项目,参考地址 http://www.cnblogs.com/i-tao/p/8878562.html
2.开启Redis服务器
./bin/redis-server redis.conf
ps -ef|grep redis
3.SpringBoot整合Redis
3.1 在application.properties文件里面添加Redis服务器信息
#整合redis spring.redis.host=192.168.*.* //redis IP地址 spring.redis.port=6379 //端口号
3.2 在项目pom.xml文件里面添加Redis依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> <version>1.3.8.RELEASE</version> </dependency>
3.3 在项目入口开启Redis缓存@EnableCaching
package com.tao.springboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; /** * Hello world! * */ @SpringBootApplication @EnableCaching public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } }
3.4 在项目需要缓存的service层添加缓存@Cacheable
package com.tao.springboot.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import com.tao.springboot.mapper.UserMapper; import com.tao.springboot.model.User; import com.tao.springboot.service.UserService; @Service public class UserServiceImpl implements UserService{ @Autowired private UserMapper userMapper; @Override @Cacheable(value = "AllUser")//设置缓存 public List<User> findAll() { // TODO Auto-generated method stub return userMapper.findAll(); } }
//常用缓存注解
@Cacheable//设置缓存 @CacheEvict//移除缓存 @CachePut//加入缓存
3.5 启动SpringApplication
4.测试是否使用了缓存
4.1 浏览器访问:http://localhost:8080/User/findAll
清空控制台重新刷新页面,数据不变,控制台没有日志输出
重启项目,清空日志,在访问一次。
4.2 连接Redis客户端查询缓存是否存在:
./bin/redis-cli
keys *
SpringBoot整合Redis单机版本缓存结束。
第二种:springboot整合redis
1.maven依赖
<!--redis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <exclusions> <exclusion> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </exclusion> <exclusion> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency>
2.RedisConfig配置
import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import redis.clients.jedis.JedisPoolConfig; @Configuration @AutoConfigureAfter(RedisAutoConfiguration.class) public class RedisConfig { @SuppressWarnings("deprecation") @Bean @ConfigurationProperties(prefix="redis") JedisConnectionFactory jedisConnectionFactory() { JedisConnectionFactory factory = new JedisConnectionFactory(); factory.setPoolConfig(jedisPoolConfig()); return factory; } @Bean @ConfigurationProperties(prefix="redis.jedis.pool") public JedisPoolConfig jedisPoolConfig() { return new JedisPoolConfig(); } @Bean @SuppressWarnings("all") RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值 Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper mapper = new ObjectMapper(); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); serializer.setObjectMapper(mapper); template.setValueSerializer(serializer); //使用StringRedisSerializer来序列化和反序列化redis的key值 template.setKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(serializer); template.afterPropertiesSet(); return template; } }
3.RedisUtil工具类
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.script.DefaultRedisScript; import org.springframework.data.redis.core.script.RedisScript; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.util.Collections; import java.util.concurrent.TimeUnit; @Component public class RedisUtil { private static final Long SUCCESS = 1L; @Autowired private RedisTemplate<String, Object> redisTemplate; /** * 指定缓存失效时间 * * @param key 键 * @param time 时间(秒) * @return */ public boolean expire(String key, long time) { try { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } return true; } catch (Exception e) { return false; } } /** * 根据key 获取过期时间 * * @param key 键 不能为null * @return 时间(秒) 返回0代表为永久有效 */ public long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } /** * 判断key是否存在 * * @param key 键 * @return true 存在 false不存在 */ public boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { return false; } } /** * 删除缓存 * * @param key 可以传一个值 或多个 */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } /** * 普通缓存获取 * * @param key 键 * @return 值 */ public Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 普通缓存放入 * * @param key 键 * @param value 值 * @return true成功 false失败 */ public boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 普通缓存放入并设置时间 * * @param key 键 * @param value 值 * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 * @return true成功 false 失败 */ public boolean set(String key, Object value, long time) { try { if (time > 0) { redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); } else { set(key, value); } return true; } catch (Exception e) { return false; } } /** * 递增 * * @param key 键 * @param delta 要增加几(大于0) * @return */ public long incr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递增因子必须大于0"); } return redisTemplate.opsForValue().increment(key, delta); } /** * 递减 * * @param key 键 * @param delta 要减少几(小于0) * @return 147 */ public long decr(String key, long delta) { if (delta < 0) { throw new RuntimeException("递减因子必须大于0"); } return redisTemplate.opsForValue().increment(key, -delta); } /** * 获取分布式锁 * * @param lockKey 锁 * @param requestId 请求标识 * @param expireTime 单位秒 * @param waitTimeout 单位毫秒 * @return 是否获取成功 */ public boolean tryLock(String lockKey, String requestId, int expireTime, long waitTimeout) { long nanoTime = System.nanoTime(); // 当前时间 try { String script = "if redis.call('setNx',KEYS[1],ARGV[1]) then if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('expire',KEYS[1],ARGV[2]) else return 0 end end"; int count = 0; do { RedisScript<String> redisScript = new DefaultRedisScript<>(script, String.class); Object result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey), requestId, expireTime); if (SUCCESS.equals(result)) { return true; } Thread.sleep(500L);//休眠500毫秒 count++; } while ((System.nanoTime() - nanoTime) < TimeUnit.MILLISECONDS.toNanos(waitTimeout)); } catch (Exception e) { e.printStackTrace(); } return false; } /** * 释放锁 * * @param lockKey 锁 * @param requestId 请求标识 * @return 是否释放成功 */ public boolean releaseLock(String lockKey, String requestId) { String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"; RedisScript<String> redisScript = new DefaultRedisScript<>(script, String.class); Object result = redisTemplate.execute(redisScript, Collections.singletonList(lockKey), requestId); if (SUCCESS.equals(result)) { return true; } return false; } }
#redis配置
redis:
host: 127.0.0.1
port: 6379
password: 123456
database: 0
jedis:
pool:
# 最大活跃链接数 默认8
max-active: 5
# 最大空闲连接数 默认8
max-idle: 10
# 最小空闲连接数 默认0
min-idle: 0