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

原文地址:https://www.cnblogs.com/jwen1994/p/12247001.html