美文网首页
(一)Spring-Boot 整合 Redis,整合Spring

(一)Spring-Boot 整合 Redis,整合Spring

作者: awaa | 来源:发表于2020-01-05 21:29 被阅读0次

    1.引入依赖包

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

    Spring Boot 提供了对 Redis 集成的组件包:spring-boot-starter-data-redis,spring-boot-starter-data-redis依赖于spring-data-redis 和 lettuce 。

    2.添加配置文件

    spring.redis.host=192.168.1.1
    spring.redis.database=15
    spring.redis.port=6379
    spring.redis.password=******
    

    注入的是 RedisProperties
    前缀是spring.redis

    @ConfigurationProperties(prefix = "spring.redis")
    public class RedisProperties{
          // 部分代码
    
        /**
         * Database index used by the connection factory.
         */
        private int database = 0;
    
        /**
         * Connection URL. Overrides host, port, and password. User is ignored. Example:
         * redis://user:password@example.com:6379
         */
        private String url;
    
        /**
         * Redis server host.
         */
        private String host = "localhost";
    
        /**
         * Login password of the redis server.
         */
        private String password;
    
        /**
         * Redis server port.
         */
        private int port = 6379;
    }
    

    3.使用RedisTemplate操作redis库

    spring-boot-redis实现了两种模板类。
    RedisTemplate 和 StringRedisTemplate 。

    经常使用的redis操作一般都是操作String类型的,没有特殊需要可以先使用》
    StringRedisTemplate,当然RedisTemplate 是都支持的。

    为了方便操作缓存对象,可以自己实现不同类型的RedisTemplate。
    文章后面的RedisConfig也实现了RedisTemplate<String, Serializable> ,方便我们操作可序列化对象

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnClass(RedisOperations.class)
    @EnableConfigurationProperties(RedisProperties.class)
    @Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
    public class RedisAutoConfiguration {
    
        @Bean
        @ConditionalOnMissingBean(name = "redisTemplate")
        public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
                throws UnknownHostException {
            RedisTemplate<Object, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }
    
        @Bean
        @ConditionalOnMissingBean
        public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
                throws UnknownHostException {
            StringRedisTemplate template = new StringRedisTemplate();
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }
    
    }
    

    操作redis库

        @Autowired
        private StringRedisTemplate stringRedisTemplate;
        @Autowired
        private RedisTemplate<String, Serializable> redisCacheTemplate;
    
        @Test
        void testRedis1() {
            stringRedisTemplate.opsForValue().set("key", "value");
            String keu = stringRedisTemplate.opsForValue().get("keu");
        }
    
        @Test
        void testRedis2() {
            redisCacheTemplate.opsForValue().set("user" ,new User(1l ,"jim2"));
            User user = (User) redisCacheTemplate.opsForValue().get("user");
            System.out.println(user.toString());
        }
    
    

    模板类提供了多种操作redis库的方法,各种神奇的用法,等用到再去探索吧

    当然为了更方便的使用,我们可以再把redis操作封装一层

    @Component
    public class RedisUtils {
    
        @Autowired
        private StringRedisTemplate stringRedisTemplate;
    
        public String get(String key) {
            return stringRedisTemplate.opsForValue().get(key);
        }
    
        public void set(String key ,String value) {
            stringRedisTemplate.opsForValue().set(key, value);
        }
    }
    

    4.使用spring-boot + redis实现缓存数据

    spring-boot帮我们集成了SpringCache方便使用缓存。
    缓存数据的key的规则。

    @Configuration
    @EnableCaching
    @AutoConfigureAfter(RedisAutoConfiguration.class)
    public class RedisConfig extends CachingConfigurerSupport {
    
        @Bean
        @Override
        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("::");
                    sb.append(method.getName());
                    for (Object obj : params) {
                        sb.append(obj.toString());
                    }
                    return sb.toString();
                }
            };
        }
    
        /**
         * 默认情况下的模板只能支持RedisTemplate<String, String>,也就是只能存入字符串,因此支持序列化
         */
        @Bean
        public RedisTemplate<String, Serializable> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) {
            RedisTemplate<String, Serializable> template = new RedisTemplate<>();
            template.setKeySerializer(new StringRedisSerializer());
            template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
            template.setConnectionFactory(redisConnectionFactory);
            return template;
        }
    
        /**
         * 配置使用注解的时候缓存配置,默认是序列化反序列化的形式,加上此配置则为 json 形式
         */
        @Bean
        public CacheManager cacheManager(RedisConnectionFactory factory) {
            // 配置序列化
            RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
            RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
    
            return RedisCacheManager.builder(factory).cacheDefaults(redisCacheConfiguration).build();
        }
    
    
    }
    
    

    当我们访问/test接口时,返回的数据就保存到了redis库中.
    @Cacheable主动开启缓存

    @RestController
    public class TestController {
    
        @GetMapping("/test")
        @Cacheable(value = "testKey")
        public String getAa() {
    
            return "Hello";
        }
    
    }
    

    缓存的其他使用方式。
    下面参考其他作者的例子。

     /**
         * 查询出一条数据并且添加到缓存
         *
         * @param userId
         * @return
         */
        @RequestMapping("/getUser")
        @Cacheable("userCache")
        public User getUser(@RequestParam(required = true) String userId) {
            System.out.println("如果没有缓存,就会调用下面方法,如果有缓存,则直接输出,不会输出此段话");
            return userDao.getUser(Integer.parseInt(userId));
        }
    
        /**
         * 删除一个缓存
         *
         * @param userId
         * @return
         */
        @RequestMapping(value = "/deleteUser")
        @CacheEvict("userCache")
        public String deleteUser(@RequestParam(required = true) String userId) {
            return "删除成功";
        }
    
        /**
         * 添加一条保存的数据到缓存,缓存的key是当前user的id
         *
         * @param user
         * @return
         */
        @RequestMapping("/saveUser")
        @CachePut(value = "userCache", key = "#result.userId +''")
        public User saveUser(User user) {
            return user;
        }
    
    
        /**
         * 返回结果userPassword中含有nocache字符串就不缓存
         *
         * @param userId
         * @return
         */
        @RequestMapping("/getUser2")
        @CachePut(value = "userCache", unless = "#result.userPassword.contains('nocache')")
        public User getUser2(@RequestParam(required = true) String userId) {
            System.out.println("如果走到这里说明,说明缓存没有生效!");
            User user = new User(Integer.parseInt(userId), "name_nocache" + userId, "nocache");
            return user;
        }
    
    
        @RequestMapping("/getUser3")
        @Cacheable(value = "userCache", key = "#root.targetClass.getName() + #root.methodName + #userId")
        public User getUser3(@RequestParam(required = true) String userId) {
            System.out.println("如果第二次没有走到这里说明缓存被添加了");
            return userDao.getUser(Integer.parseInt(userId));
        }
    
    作者:米奇罗
    链接:https://juejin.im/post/5ca07a98f265da30933fc4c4
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

    相关文章

      网友评论

          本文标题:(一)Spring-Boot 整合 Redis,整合Spring

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