美文网首页
springboot使用redis做缓存

springboot使用redis做缓存

作者: 则一城终老 | 来源:发表于2019-04-15 17:10 被阅读0次
    此文纯属第一次用redis时记的笔记;
    1 .springboot整合redis有两种方式:分别是jedis连接和redisTemplate
    • jedis是redis官方推荐的面向java的操作redis的客户端,存储起来的是字符串
    • 而redisTemplate是springDataRedis中对jedisapi的高度封装,存储的是二进制字节编码。其实在spring boot的官网上我们也能看到,官方现在推荐的是springdataredis形式相对于jedis来说可以方便的更换redis的java客户端,其比jedis多了自动管理连接池的特性,方便与其他spring框架进行搭配使用。例如:SpringCache;
    2 .pom.xml中引入jar宝版本
    • springboot1.4版本以前依赖为spring-boot-starter-redis:
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-redis</artifactId>
        <version>1.3.2.RELEASE</version>
    </dependency>
    
    • b.springboot1.4版本后依赖为spring-boot-starter-data-redis:
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-redis</artifactId>
        <version>1.3.2.RELEASE</version>
    </dependency>
    
    • c.如果用jedis 就是 redis.clients
    <dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.9.0</version>
    </dependency>
    
    3. 引入jar包之后,我们再来看看配置文件:application.yml
    # redis单服务器配置
    spring:   
      redis:
        database: 0 # 使用第一个数据库,默认一共创建16个数据库
        host: 10.175.94.63  # Redis服务器地址  测试服务器中的redis
        port: 6379 # Redis服务器连接端口  
        password: # Redis服务器连接密码(默认为空) 
        pool:
          max-active: 8 # 连接池最大连接数(使用负值表示没有限制) 
          max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
          max-idle: 8 # 连接池中的最大空闲连接
          min-idle: 0 # 连接池中的最小空闲连接
        timeout: 0 # 连接超时时间(毫秒)
        commandTimeout: 5000
    
    4 . 再来看看序列化问题:请参考 https://blog.csdn.net/f641385712/article/details/84679456,我觉得讲的很具体;

    这边写一下比较常用的几种,大家酌情选用:

    @Configuration
    @EnableCaching // 启用缓存,这个注解很重要
    public class RedisConfig  implements CachingConfigurer{
    
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    //-----------------------序列化配置-------------------------------
    @Bean
        public RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory factory) {
            RedisTemplate<?, ?> redisTemplate = new RedisTemplate<>();
            redisTemplate.setConnectionFactory(factory);
            // key序列化方式;但是如果方法上有Long等非String类型的话,会报类型转换错误;
            RedisSerializer<String> redisSerializer = new StringRedisSerializer();// Long类型不可以会出现异常信息;
            redisTemplate.setKeySerializer(redisSerializer);
            redisTemplate.setHashKeySerializer(redisSerializer);
    
            // JdkSerializationRedisSerializer序列化方式;
            JdkSerializationRedisSerializer jdkRedisSerializer = new JdkSerializationRedisSerializer();
            redisTemplate.setValueSerializer(jdkRedisSerializer);
            redisTemplate.setHashValueSerializer(jdkRedisSerializer);
            redisTemplate.afterPropertiesSet();
            
            // Json序列化方式
    //      Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
    //      ObjectMapper om = new ObjectMapper();
    //      om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    //      om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    //      jackson2JsonRedisSerializer.setObjectMapper(om);
    //      RedisSerializer stringSerializer = new StringRedisSerializer();
    //      redisTemplate.setKeySerializer(stringSerializer);// key序列化;
    //      redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化 
    //      redisTemplate.setHashKeySerializer(stringSerializer);//Hash key序列化
    //      redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);//Hash value序列化 
    //      redisTemplate.afterPropertiesSet();
            
            return redisTemplate;
        }
    
    
    //------------------------连接配置---------------------------------------
    
    
    
    
        @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;
    
        @Value("${spring.redis.pool.max-idle}")
        private int maxIdle;
    
        @Value("${spring.redis.pool.min-idle}")
        private int minIdle;
    /**
         * redis连接的基础设置
         * 
         * @Description:
         * @return
         */
        @Bean
        public JedisConnectionFactory redisConnectionFactory() {
            JedisConnectionFactory factory = new JedisConnectionFactory();
            factory.setHostName(host);
            factory.setPort(port);
            factory.setPassword(password);
            // 存储的库
            factory.setDatabase(database);
            // 设置连接超时时间
            factory.setTimeout(timeout);
            factory.setUsePool(true);
            factory.setPoolConfig(jedisPoolConfig());
            return factory;
        }
    
        /**
         * 连接池配置
         * 
         * @Description:
         * @return
         */
        @Bean
        public JedisPoolConfig jedisPoolConfig() {
            JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
            jedisPoolConfig.setMaxIdle(maxIdle);
            jedisPoolConfig.setMinIdle(minIdle);
            // jedisPoolConfig.set ...
            return jedisPoolConfig;
        }
    
        /**
         * redis数据操作异常处理 这里的处理:在日志中打印出错误信息,但是放行
         * 保证redis服务器出现连接等问题的时候不影响程序的正常运行,使得能够出问题时不用缓存
         * 
         * @return
         */
        @Bean
        @Override
        public CacheErrorHandler errorHandler() {
            CacheErrorHandler cacheErrorHandler = new CacheErrorHandler() {
                @Override
                public void handleCacheGetError(RuntimeException e, Cache cache, Object key) {
                    logger.error("redis异常:key=[{}]", key, e);
                }
    
                @Override
                public void handleCachePutError(RuntimeException e, Cache cache, Object key, Object value) {
                    logger.error("redis异常:key=[{}]", key, e);
                }
    
                @Override
                public void handleCacheEvictError(RuntimeException e, Cache cache, Object key) {
                    logger.error("redis异常:key=[{}]", key, e);
                }
    
                @Override
                public void handleCacheClearError(RuntimeException e, Cache cache) {
                    logger.error("redis异常:", e);
                }
            };
            return cacheErrorHandler;
        }
    
    }
    
    
    5. key的自定义策略:
    @Configuration
    public class RedisConfig{
    /**
         * 注解@Cache key生成规则
         */
        @Bean
        public KeyGenerator keyGenerator() {
            return new KeyGenerator() {
                @Override
                public Object generate(Object target, Method method, Object... params) {
                    StringBuilder sb = new StringBuilder();
                    sb.append(target.getClass().getName());
                    sb.append(method.getName());
                    for (Object obj : params) {
                        sb.append(obj.toString());
                    }
                    return sb.toString();
                }
    
            };
        }
    
    
          /**
         * 
         * @Title: appProjectCacheKeyGenerator
         * @Description: 自定key生成規則
         * @author admin
         * @return
         */
        @Bean
        public KeyGenerator appProjectCacheKeyGenerator() {
            AppProjectCacheKeyGenerator apckg = new AppProjectCacheKeyGenerator();
            return apckg;
        }
    }
    

    上面自定义key中的AppProjectCacheKeyGenerator是👇自定义的keyGenerator

    public class AppProjectCacheKeyGenerator implements KeyGenerator {
    
        @Override
        public Object generate(Object target, Method method, Object... params) {
            return "MODEL-USER-ROLE";//自定义的key;
        }
    
    }
    

    这个KeyGenerator在注解缓存中的用法如下:相当于自定义key

    
    @Cacheable(value = "user-resource",  keyGenerator = "appProjectCacheKeyGenerator")
        public List<GroupLevel> listuser() {
            return groupUserMapper.listAllUser();
        }
    
    
    6. 关于注解:
    • @Cacheable:表明spring在调用方法之前,手下应该在缓存中查找方法的返回值,如果这个值能被找到,就会返回缓存的值,否则的话,这个方法就会被调用,返回值会放到缓存之中;
      语法: @Cacheable(value = "redis", keyGenerator = "cacheKeyGenerator")
      value:缓存位置的一段名称,不能为空;
      key:缓存的key,默认为空,表示使用方法的参数类型及参数值作为key;
      keyGenerator:指定key的生成策略;
      condition:触发条件,满足条件就加入缓存,默认为空,表示全部加入缓存;

    • @CacheEvict :
      语法:@CacheEvict(value = "redis", allEntries = true) 清除缓存
      value:缓存位置的一段名称,不能为空
      key:缓存的key,默认为空,表示使用方法的参数类型及参数值作为key,支持SpEL
      condition:触发条件,满足条件就加入缓存,默认为空,表示全部都加入缓存,支持SpEL
      allEntries:true表示清除value中的全部缓存,默认为false

    相关文章

      网友评论

          本文标题:springboot使用redis做缓存

          本文链接:https://www.haomeiwen.com/subject/declwqtx.html