• Spring Boot 使用 Cache 缓存


    步骤一:引入 spring-boot-starter-cache 依赖

    <!-- 引入Spring缓存依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>

    步骤二:启动类上使用注解 @EnableCaching 开启缓存

    package com.haitaiinc.clinicpathservice;
    
    import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cache.annotation.EnableCaching;
    
    @SpringBootApplication
    @MapperScan("com.haitaiinc.clinicpathservice.mapper")
    @EnableAutoConfiguration(exclude={DruidDataSourceAutoConfigure.class})
    @EnableCaching
    public class ClinicPathServiceApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ClinicPathServiceApplication.class, args);
        }
    
    }

    步骤三:使用缓存注解

    @Service
    @CacheConfig(cacheNames = "switchCfgCache")//抽取缓存的公共配置
    public class SwitchProjService {
        @Autowired
        SwitchProjDao switchProjDao;
    
        @Cacheable()
        public List<SwitchProj> getAllSwitchProj(){
            return switchProjDao.getAllSwitchProj();
        }
    
        @Cacheable(key = "#id")
        public SwitchProj getSwitchProjById(String id){
            return switchProjDao.getSwitchProjById(id);
        }
    }

    Spring Boot Cache 存在以下问题:

    1. 生成 key 过于简单,容易冲突 switchCfgCache::3
    2. 无法设置过期时间,默认过期时间为永久不过期
    3. 无法配置序列化方式,默认的序列化是 JDK Serialazable

    那么为了解决以上问题,我们可以新增配置类,增加一些方法

    package com.haitaiinc.clinicpathservice.config;
    
    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.cache.CacheManager;
    import org.springframework.cache.annotation.EnableCaching;
    import org.springframework.cache.interceptor.KeyGenerator;
    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.cache.RedisCacheWriter;
    import org.springframework.data.redis.connection.RedisConnectionFactory;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
    import org.springframework.data.redis.serializer.RedisSerializationContext;
    
    import java.time.Duration;
    import java.util.HashMap;
    import java.util.Map;
    
    @Configuration
    @EnableCaching
    public class RedisConfiguration {
    
        @Bean
        public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory redisConnectionFactory){
            RedisTemplate<String,String> redisTemplate = new RedisTemplate<>();
            redisTemplate.setConnectionFactory(redisConnectionFactory);
            return redisTemplate;
        }
    
        @Bean
        public KeyGenerator simpleKeyGenerator() {
            return (o, method, objects) -> {
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append(o.getClass().getSimpleName());
                stringBuilder.append(".");
                stringBuilder.append(method.getName());
                stringBuilder.append("[");
                for (Object obj : objects) {
                    stringBuilder.append(obj.toString());
                }
                stringBuilder.append("]");
    
                return stringBuilder.toString();
            };
        }
    
        @Bean
        public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
            return new RedisCacheManager(
                    RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory),
                    this.getRedisCacheConfigurationWithTtl(600), // 默认策略,未配置的 key 会使用这个
                    this.getRedisCacheConfigurationMap() // 指定 key 策略
            );
        }
    
        private Map<String, RedisCacheConfiguration> getRedisCacheConfigurationMap() {
            Map<String, RedisCacheConfiguration> redisCacheConfigurationMap = new HashMap<>();
            redisCacheConfigurationMap.put("SwitchCfgList", this.getRedisCacheConfigurationWithTtl(100));
    
            return redisCacheConfigurationMap;
        }
    
        private RedisCacheConfiguration getRedisCacheConfigurationWithTtl(Integer seconds) {
            Jackson2JsonRedisSerializer<Object> 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);
    
            RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
            redisCacheConfiguration = redisCacheConfiguration.serializeValuesWith(
                    RedisSerializationContext
                            .SerializationPair
                            .fromSerializer(jackson2JsonRedisSerializer)
            ).entryTtl(Duration.ofSeconds(seconds));
    
            return redisCacheConfiguration;
        }
    
    }

    然后对我们的代码进行修改,注意配置类中标红的部分和代码修改后的内容(上面配置类中会被代码编辑器标出一些红色,但不影响编译运行)

    @Service
    @CacheConfig(cacheNames = "switchCfgCache")//抽取缓存的公共配置
    public class SwitchProjService {
        @Autowired
        SwitchProjDao switchProjDao;
    
        @Cacheable(value="SwitchCfgList", keyGenerator = "simpleKeyGenerator")
        public List<SwitchProj> getAllSwitchProj(){
            return switchProjDao.getAllSwitchProj();
        }
    
        @Cacheable(keyGenerator = "simpleKeyGenerator")
        public SwitchProj getSwitchProjById(String id){
            return switchProjDao.getSwitchProjById(id);
        }
    }

    下图显示的是效果:

     也可以查看到缓存的有效时间

    Redis 实现分布式集群配置 sessionId 过程

    步骤一:引入依赖

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

    步骤二:启动类增加注解 @EnableRedisHttpSession(maxInactiveIntervalInSeconds= 50)

    @EnableRedisHttpSession 开启 Redis Session 缓存

    maxInactiveIntervalInSeconds 指定缓存的时间 spring:session:sessions:expires:+‘sessionId’ 的过期时间  

    步骤三:测试

    @RestController
    public class TestController {
    
        @GetMapping("/setSession")
        public Map<String, Object> setSession (HttpServletRequest request){
            Map<String, Object> map = new HashMap<>();
            request.getSession().setAttribute("request Url", request.getRequestURL());
            map.put("request Url", request.getRequestURL());
            return map;
        }
    
        @GetMapping("/getSession")
        public Object getSession (HttpServletRequest request){
            Map<String, Object> map = new HashMap<>();
            map.put("sessionIdUrl",request.getSession().getAttribute("request Url"));
            map.put("sessionId", request.getSession().getId());
            return map;
        }
    }

    效果如下图所示:

    官方说明:

    https://docs.spring.io/spring/docs/5.2.3.RELEASE/spring-framework-reference/integration.html#cache

    参考博文:

    https://blog.csdn.net/weixin_43907332/article/details/91610493

    https://blog.csdn.net/rubulai/article/details/85015074

    https://blog.csdn.net/leiliz/article/details/98035397

  • 相关阅读:
    抽象工厂例子
    学习boost::asio一些小例子
    boost::asio学习(定时器)
    共享内存
    网络流程图
    粘包
    端游服务器群
    38 写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度。
    37 有n个人围成一圈,顺序排号,从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号那位.
    36 有n个整数,使其前面各数顺序向后移n个位置,最后m个数变成最前面的m个数
  • 原文地址:https://www.cnblogs.com/jwen1994/p/12247001.html
Copyright © 2020-2023  润新知