开发技术我爱编程后端世界

SpringBoot项目整合Redis及遇到的问题

2018-05-27  本文已影响228人  作草分茶

1、Springboot整合redis所需的依赖。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

2、redis相关配置bean。

新建redisconfig.java,继承自CachingConfigurerSupport。

  1. 配置redis key默认生成器。keyGenerator是默认的key生成器,这里用 包名+类名+方法名+所有参数生成key。
@Override
@Bean
public KeyGenerator keyGenerator() {
    return (target, method, params) -> {
        StringBuilder sb = new StringBuilder();
        sb.append(target.getClass().getName());
        sb.append(".");
        sb.append(method.getName());
        for (Object obj : params) {
            sb.append(".");
            sb.append(obj.toString());
        }
        return sb.toString();
    }
 }
  1. 配置项目model的key的生成策略。用 包名+方法名+返回类名+model的Id。
@Bean
public KeyGenerator modelKeyGenerator() {
     return (target, method, params) -> {
        StringBuilder sb = new StringBuilder();
        sb.append(target.getClass().getName());
        sb.append(".");
        Class<?> clazz = method.getReturnType();
        sb.append(clazz.getSimpleName());
        sb.append(".");
        try {
            for (Object obj : params) {
                if (obj instanceof Long) {
                    sb.append(obj.toString());
                } else {
                    Class<?> superclass = obj.getClass().getSuperclass();
                    Field field = superclass.getDeclaredField("id");
                    if (field != null) {
                        field.setAccessible(true);
                        sb.append(field.get(obj).toString());
                    }
                }
            }
        } catch (IllegalAccessException | NoSuchFieldException e) {
            e.printStackTrace();
        }
        return sb.toString();
    };
}
  1. 配置SpringBoot的缓存为RedisCacheManage。
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
    RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
    Map<String, Long> map = new HashMap<>(2);
    //token对应登录的账号,过期时间2小时
    map.put(RedisKeys.TOKEN_ACCOUNT, 2L * 60 * 60);
    //普通缓存,5分钟过期
    map.put(RedisKeys.MODEL, 5L * 60);
    cacheManager.setExpires(map);
    return cacheManager;
}
  1. 配置RedisTemplate,后面通过代码操作redis需要用到。
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
    RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
    template.setConnectionFactory(factory);
    template.setKeySerializer(new StringRedisSerializer());
    //使用jdk自带的序列化
    template.setValueSerializer(new JdkSerializationRedisSerializer());
    return template;
}

3、在项目中使用Redis缓存。

  1. 使用java代码方式操作redis。
@Service
public class RedisHelper<T> implements IRedisHelper<T> {

    private final RedisTemplate<String, Object> redisTemplate;
    private final StringRedisTemplate stringRedisTemplate;

    @Autowired
    public RedisHelper(RedisTemplate<String, Object> redisTemplate, StringRedisTemplate stringRedisTemplate) {
        this.redisTemplate = redisTemplate;
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Override
    @SuppressWarnings("unchecked")
    public T getValue(String key) {
        return (T) redisTemplate.opsForValue().get(key);
    }

    @Override
    public void setValue(String key, T data) {
        redisTemplate.opsForValue().set(key, data);
    }

    @Override
    public String getString(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    @Override
    public void setString(String key, String value) {
        stringRedisTemplate.opsForValue().set(key,value);
    }
}
  1. 注解方式操作redis。首先说下 @Cacheable、@CachePut和@CacheEvict的区别。
    • @Cacheable:每次一执行该方法之前,都会在缓存中查找该key是否有所对应的缓存,如果有则在缓存中取出且不再进入该方法。如果没有则执行该方法,将返回值存到redis中。
    • @CachePut:和@Cacheable不同,每次都会调用该方法,然后将返回值存到redis中。
    • @CacheEvict:删除该key及所对应的value。
      三个注解都有几个相同的属性。
    • value:缓存名字。相当于分类,在CacheManage中可以配置缓存的过期时间。
    • key:键的名字。可以根据业务自定义。
    • keyGenerator:和key属性冲突,两者只能存在一个。根据所配置的keyGenerator生成key,如果key和keyGenerator都没有填,则按默认的keyGenerator生成key。
@Override
@CachePut(value = RedisKeys.TOKEN_ACCOUNT, key = "'token_account_'+#token")
public AccountEntity setIntoCacheByToken(String token, AccountEntity account) {
    return account;
}
@Cacheable(value = RedisKeys.ROLE_RESOURCE_TREE)
public List<ResourceEntity> findResourceTreeByRoleId(Long roleId) {
    RoleEntity role = roleService.findById(roleId);
    return role.getResources();
}

4、开发过程中所遇到的坑。

上一篇 下一篇

猜你喜欢

热点阅读