SpringBoot配置Redis緩存


引入依賴

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

不需要引入spring-boot-starter-cache依賴

應用程序配置

spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.cache.type=redis

編寫Redis配置類

Redis緩存和RedisTemplate序列化時默認使用JDK序列化,在Redis客戶端查看時會出現亂碼,需要修改序列化方案

SpringBoot2.x開始,RedisCacheManager持有的RedisCacheWriter(負責操作Redis)不依賴RedisTemplate,這兩個API需要分別修改序列化方案(用哪個API修改哪個,如果只是使用Redis緩存不需要修改RedisTemplate)

@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    // 自定義key生成策略,按類名+方法名+參數名命名
    @Bean
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder key = new StringBuilder();
                key.append(target.getClass().getName());
                key.append(method.getName());
                for (Object param : params) {
                    key.append(param.toString());
                }
                return key.toString();
            }
        };
    }

    // 緩存管理器
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        // 因為每步會生成新的對象,所以必須鏈式調用
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofDays(1))
                // 設置序列化方式,否則客戶端會呈現為二進制字符,value使用JSON序列化,key用String序列化
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
                .disableCachingNullValues();

        // RedisCacheManager構造器需要兩個參數:
        // RedisCacheWriter, 負責操作redis,不依賴redisTemplate
        // RedisCacheConfiguration, 設置redis緩存配置

        // 創建無鎖的RedisCacheWriter
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(factory);
        return RedisCacheManager.builder(redisCacheWriter).cacheDefaults(redisCacheConfiguration).build();
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();

        redisTemplate.setConnectionFactory(factory);
	redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());

        return redisTemplate;
    }
}

RedisCacheConfiguration配置時,每調用一次方法會生成一個新的RedisCacheConfiguration,所以必須鏈式調用

serializeKeysWith方法需要SerializationPair類型的入參,使用靜態方法RedisSerializationContext.SerializationPair.fromSerializer生成

RedisCacheManager構造器需要兩個參數:RedisCacheWriter(負責操作Redis)和RedisCacheConfiguration

RedisCacheWriter.nonLockingRedisCacheWriter靜態方法創建無鎖的RedisCacheWriter

RedisCacheManager.builder方法接受RedisCacheWriterRedisConnectionFactory類型的入參,返回RedisCacheManagerBuilder建造器,cacheDefaults方法指定緩存配置類,build方法生成RedisCacheManager實例

SpringBoot默認引入的RedisTemplateRedisTemplate<Object, Object>類型,默認使用JDK的序列化機制,會出現亂碼,需要重寫Redis配置

鍵(含Hash類型的鍵)使用StringRedisSerializer序列化,值(含Hash類型的值)使用GenericJackson2JsonRedisSerializer序列化

其他配置

  1. 入口類配置@EnableCaching
  2. Service類添加緩存注解(@CacheConfig、@Cacheable、@CachePut、@CacheEvict)
  • @CacheConfig標記在類上,統一配置緩存名
  • @Cacheable,方法調用時先查詢緩存,沒有緩存從數據庫加載數據
  • @CachePut,先執行方法調用,方法執行完后把結果寫入緩存
  • @CacheEvict,方法調用完后把緩存清空
@Service
@CacheConfig(cacheNames = "book")
public class BookServiceImpl implements BookService {
    @Autowired
    private BookDao bookDao;

    @CachePut(key = "#p0")
    public void update(Book book) {
        bookDao.save(book);
    }

    @CacheEvict(key ="#p0",allEntries=true)
    public void delete(long id) {
        bookDao.deleteById(id);
    }

    @Cacheable(key ="#p0")
    public Book findById(long id) {
        return bookDao.findById(id);
    }
}

注意:

  1. 運行應用時,Redis服務器要處於運行狀態
  2. 運行應用是,spring-boot-devtools熱部署工具要停用

參考

Spring Boot 集成Spring Cache 和 Redis
[springboot配置redis緩存
SpringBoot實戰派-第十一章


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM