springboot配置基於redis的緩存(一)

springboot配置基於redis的緩存

一引入必要的maven依賴

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

配置RedisConfig

  • 在application.yaml添加對應的redis配置信息
  # redis 配置
spring:  
  redis:
    database: 0
    cluster:
      max-redirects: 3
      nodes:
        - 192.168.15.208:7001
        - 192.168.15.208:7002
        - 192.168.15.208:7003
        - 192.168.15.208:7004
        - 192.168.15.208:7005
        - 192.168.15.208:7006

    #password: 1234
    lettuce:
      pool:
        max-active: 1000
        max-wait: -1
        max-idle: 10
        min-idle: 5
    timeout: 3000
  data:
    redis:
      repositories:
        enabled: false

  • 添加自動化配置類
/**
 * @author lyy
 * @date 2021/6/21
 */
@Configuration
@EnableCaching
@SuppressWarnings("all")
public class RedisConfig {
    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(
            RedisConnectionFactory redisConnectionFactory) {

        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 解決jackson2無法反序列化LocalDateTime的問題
        om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        om.registerModule(new JavaTimeModule());
        om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);

        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(redisConnectionFactory);
        // template.setKeySerializer(jackson2JsonRedisSerializer);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(jackson2JsonRedisSerializer);
        template.setHashKeySerializer(jackson2JsonRedisSerializer);
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    @ConditionalOnMissingBean(StringRedisTemplate.class)
    public StringRedisTemplate stringRedisTemplate(
            RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }


   //cacheManager只針對註解緩存有效
    //只使用redisTemplate不需要配置

    @Bean
    public KeyGenerator keyGenerator() {
        return (o, method, objects) -> {
            StringBuilder sb = new StringBuilder();
            sb.append(o.getClass().getName());
            sb.append("." + method.getName() + "(");
            for (Object obj : objects) {
                sb.append(obj.toString());
            }
            sb.append(")");
            return sb.toString();
        };
    }

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
        om.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        return om;
    }


    @Bean
    public Jackson2JsonRedisSerializer jackson2JsonRedisSerializer(ObjectMapper om) {
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        return jackson2JsonRedisSerializer;
    }
    /**
     * springboot2.x中,RedisCacheManager已經沒有了單參數的構造方法
     * 1.x中通過參數redisTemplate配置的方式不可行
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory, RedisSerializer jackson2JsonRedisSerializer) {
        RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofHours(1))  // 設置緩存有效期一小時
                .disableCachingNullValues()
                .computePrefixWith(cacheName -> "ants_sale_white".concat(":").concat(cacheName).concat(":"))
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));

        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(cacheConfiguration)
                .build();
    }


}

注意:需要先在RedisConfig加上@EnableCaching,表示開啓緩存功能

啓用spring 註解緩存

@Service(value = "UserServer")
@CacheConfig(cacheNames = "user")
public class UserServer implements com.ants.furun.sale_white_board.servers.api.UserServer {
    @Override
    @CachePut(key = "'ants-'+#userPo.id")
    public UserPo addUser(UserPo userPo) {
        return userPo;
    }

    @Override
    @CacheEvict(key="'ants-'+#p0")
    public int deleteUser(int id) {
        return 0;
    }

    @Override
    @Cacheable(key = "'ants-'+#p0")
    public UserPo getUser(int id) {
        return null;
    }
}

其中#p0是指的第一個參數,#p1是第二個參數,以此類推。

此時我們查看redis可以看到緩存的結果

redis-session

相關注解說明

  1. @EnableCaching

    開啓緩存功能,一般放在啓動類上或者自定義的RedisConfig配置類上

  2. @CacheConfig

    使用@CacheConfig(cacheNames="cacheName")註解在類上,用來指定統一的value值,統一管理keys,這時可以在方法上省略value,如果在方法上寫了value,那麼以方法上的爲準。

  3. @Cacheable

    根據方法對返回的結果進行緩存,下次請求時,如果緩存存在,直接返回緩存數據,如果不存在,則執行方法,並把返回結果緩存,多用於查詢方法上。

    屬性/方法名 解釋
    value 緩存名,指定了緩存放在那塊空間上
    cacheNames 與value差不多,二選一
    key 緩存key,可以用SPEL標籤自定義
    keyGenerator key生成器
    cacheManager 緩存管理器
    cacheResolver 緩存解析器
    condition 條件符合則緩存
    unless 條件符合不緩存
    sync 是否使用異步模式,默認false
  4. @CachePut

    此註解標註的方法,每次都會執行,並將結果存入指定的緩存中。其它方法則可以直接讀取緩存數據。一般用在新增方法上,屬性值同@Cacheable

  5. @CacheEvict

    此註解標註的方法會清空緩存,一般用於更新或刪除方法上,屬性與@Cacheable差不多,下面是特有的

    屬性/方法名 解釋
    allEntries 是否清空所有緩存,默認false,如果指定爲true,則方法調用後立即清空所有的緩存
    beforeInvocation 是否在執行方法之前就清空緩存,默認爲false,如果指定爲true,剛方法執行前會清空所有緩存
  6. @Caching

    可以實現在同一個方法上使用多種註解

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章