SpringBoot使用 @EnableCaching 默认缓存管理器实现缓存,指定缓存时间

发布时间:2021-10-25作者:laosun阅读(83)

@CachePut、@Cacheable、@CacheEvict

    @EnableCaching注解是spring framework中的注解驱动的缓存管理功能。

    Spring3.1之后就引入了基于注解的缓存技术,但是要明白Spring基于注解的缓存技术并不是一个具体的实现方案(EHCache、OSCache、Redis才是具体的缓存方案),而是对缓存使用的一个抽象。

    基于注解的缓存能够在现有的代码基础上只需要加入少量的缓存注解(@Cacheable、@CachePut、@CacheEvict、@Caching)即能够达到缓存方法的返回结果的效果。(使用缓存注解实现缓存无需关心缓存具体的实现产品)


    开启缓存注解的步骤

    配置类上开启缓存注解支持:@EnableCaching

    1. 向容器内至少放置一个CacheManager类型的Bean

    2. 仅仅简单的两步后,就可以开工使用Spring强大的缓存注解功能了


    pom.xml

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

    redis 配置

    import org.springframework.boot.autoconfigure.AutoConfigureAfter;
    import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.redis.cache.RedisCacheConfiguration;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.RedisSerializationContext;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    import java.io.Serializable;
    import java.time.Duration;
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * redis 配置
     *
     * @author sun
     * @date 2021/10/25 20:04
     */
    @Configuration
    @AutoConfigureAfter(RedisAutoConfiguration.class)
    @EnableCaching
    public class RedisConfig {
    
        /**
         * 默认情况下的模板只能支持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 redisConnectionFactory) {
            return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(getDefaultCacheConfiguration())//默认的缓存配置(没有配置键的key均使用此配置)
                .withInitialCacheConfigurations(getCacheConfigurations())
                .transactionAware() //在spring事务正常提交时才缓存数据
                .build();
        }
    
        private Map<String, RedisCacheConfiguration> getCacheConfigurations() {
            Map<String, RedisCacheConfiguration> configurationMap = new HashMap<>();
            // 指定key值的过期时间,若没有指定,则按照通用默认过期时间来设置
            configurationMap.put("user", this.getDefaultCacheConfiguration(30));
            return configurationMap;
        }
    
        private RedisCacheConfiguration getDefaultCacheConfiguration() {
            // 通用默认过期时间
            int seconds = 60;
            RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
            RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())).entryTtl(Duration.ofSeconds(seconds)).serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
            return redisCacheConfiguration;
        }
    
        private RedisCacheConfiguration getDefaultCacheConfiguration(int seconds) {
            //设置键过期的时间,用 java.time 下的Duration表示持续时间,进入entryTtl()方法的源码中可看到
            //当设置为 0 即 Duration.ZERO 时表示键无过期时间,默认配置
            return getDefaultCacheConfiguration().entryTtl(Duration.ofSeconds(seconds));
        }
    }

    User.java

    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.io.Serializable;
    
    /**
     * 用户实体
     *
     * @author sun
     * @date 2021/10/25 20:12
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User implements Serializable {
        private static final long serialVersionUID = 2892248514883451461L;
        /**
         * 主键id
         */
        private Long id;
        /**
         * 姓名
         */
        private String name;
    }


    我们创建个controller来测试,pom.xml引入web包

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


    HelloController.java

    import cn.hutool.json.JSON;
    import cn.hutool.json.JSONUtil;
    import com.xkcoding.cache.redis.entity.User;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.cache.annotation.CacheEvict;
    import org.springframework.cache.annotation.CachePut;
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * 测试controller
     *
     * @author sun
     * @date 2021/10/25 20:10
     */
    @RestController
    @RequestMapping("hello")
    @Slf4j
    public class HelloController {
    
        @RequestMapping("index")
        public String index() {
            return "OK";
        }
    
        /**
         * 存入redis缓存(指定了key,过期时间为30秒)
         *
         * http://localhost:8080/hello/put?id=1&name=%E5%AD%99
         *
         * @author sun
         * @date 2021/10/25 20:22
         * @param user
         * @return java.lang.String
         */
        @RequestMapping("put")
        @CachePut(value = "user", key = "#user.id")
        public String put(User user) {
            JSON json = JSONUtil.parse(user);
            log.info("保存用户-{}", json);
            return json.toString();
        }
    
        /**
         * 获取redis缓存
         *
         * http://localhost:8080/hello/get?id=1
         *
         * @author sun
         * @date 2021/10/25 20:25
         * @param user
         * @return com.xkcoding.cache.redis.entity.User
         */
        @RequestMapping("get")
        @Cacheable(value = "user", key = "#user.id")
        public String get(User user) {
            JSON json = JSONUtil.parse(user);
            log.info("获取用户信息-{}", json);
            return json.toString();
        }
    
        /**
         * 删除redis缓存
         *
         * http://localhost:8080/hello/delete?id=1
         *
         * @author sun
         * @date 2021/10/25 20:25
         * @param user
         * @return com.xkcoding.cache.redis.entity.User
         */
        @RequestMapping("delete")
        @CacheEvict(value = "user", key = "#user.id")
        public String delete(User user) {
            JSON json = JSONUtil.parse(user);
            log.info("删除用户信息-{}", json);
            return json.toString();
        }
    
        /**
         * 测试过期时间(未指定key,走通用默认过期时间60秒)
         *
         * http://localhost:8080/hello/put2?id=1&name=%E5%AD%99
         *
         * @author sun
         * @date 2021/10/25 20:30
         * @param user
         * @return java.lang.String
         */
        @RequestMapping("put2")
        @CachePut(value = "newkey", key = "#user.id")
        public String put2(User user) {
            JSON json = JSONUtil.parse(user);
            log.info("保存用户-{}", json);
            return json.toString();
        }
    
    }


    SpringBoot 整合 阿里开源的缓存框架JetCache


1 +1

版权声明

 Java  源码  开源  springboot

 请文明留言

0 条评论