springboot+springCache+redis缓存中间件使用

缓存作用

  • @

    举个例子:在我们程序中,很多配置数据(例如一个商品信息、一个白名单、一个第三方客户的回调接口),这些数据存在我们的DB上,数据量比较少,但是程序访问很频繁,这种情况下,将数据放一份到我们的内存缓存中将大大提升我们系统的访问效率,因为减少了数据库访问,有可能减少了数据库建连时间、网络数据传输时间、数据库磁盘寻址时间……

    总的来说,涉及查询场景都可以考虑使用缓存优化性能:1、查数据库2、读取文件3、网络访问,特别是调用第三方服务查询接口!

    注意:并不是缓存设计的多,性能就一定好,对更新频繁的数据,不推荐缓存,保证数据一致性是缓存的前提!

    一致性解释:缓存数据和数据库数据一致,避免脏(错误)数据!

  • SpringCache概念

    Spring Cache 是Spring 提供的一整套的缓存解决方案,它不是具体的缓存实现,它只提供一整套的接口和代码规范、配置、注解等,用于整合各种缓存方案,比如Redis、Caffeine、Guava Cache、Ehcache。使用注解方式替代原有硬编码方式缓存,语法更加简单优雅!

    SpringCache使用三步骤: 导入依赖 缓存配置 添加注解

  • SpringCache依赖导入

    缓存具体实现技术,我们选择redis

<!--spring-cache-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- redis连接池-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

SpringCache配置

- application.yml 

  > 配置缓存固定的连接信息等配置!
spring:  
  cache:
    type: redis  # 缓存设置为Redis类型
  redis:  # 设置Redis连接信息
    host: 124.221.70.206
    port: 6379
    jedis: # 设置Redis连接池
      pool:
        max-wait: 2000ms
        min-idle: 2
        max-idle: 8
        max-active: 10
- 配置类

   声明缓存配置序列化方式【json】,配置缓存时间多样化配置
 //配置缓存manager
@Bean
@Primary  //同类型,多个bean,默认生效! 默认缓存时间1小时!  可以选择!
public RedisCacheManager cacheManagerHour(RedisConnectionFactory redisConnectionFactory){

    RedisCacheConfiguration instanceConfig = instanceConfig(1 * 3600L);//缓存时间1小时

    //构建缓存对象
    return RedisCacheManager.builder(redisConnectionFactory)
            .cacheDefaults(instanceConfig)
            .transactionAware()
            .build();
}

//缓存一小时配置
@Bean
public RedisCacheManager cacheManagerDay(RedisConnectionFactory redisConnectionFactory){

    RedisCacheConfiguration instanceConfig = instanceConfig(24 * 3600L);//缓存时间1小时

    //构建缓存对象
    return RedisCacheManager.builder(redisConnectionFactory)
            .cacheDefaults(instanceConfig)
            .transactionAware()
            .build();
}


/**
 * 实例化具体的缓存配置!
 *    设置缓存方式JSON
 *    设置缓存时间 单位秒
 * @param ttl
 * @return
 */
private RedisCacheConfiguration instanceConfig(Long ttl){
    
    //设置jackson序列化工具
    Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer 
            = new Jackson2JsonRedisSerializer<Object>(Object.class);
    
    //常见jackson的对象映射器,并设置一些基本属性
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    objectMapper.registerModule(new JavaTimeModule());
    objectMapper.configure(MapperFeature.USE_ANNOTATIONS,false);
    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
            ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
    
    jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
    
    return RedisCacheConfiguration.defaultCacheConfig()
            .entryTtl(Duration.ofSeconds(ttl)) //设置缓存时间
            .disableCachingNullValues()
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
}
  • SpringCache 注解

    • @EnableCaching

      添加到启动类,开启缓存支持!

@SpringBootApplication
@MapperScan(basePackages = "com.atguigu.product.mapper")
//开启feign客户端,引入对应的客户端
@EnableFeignClients(clients = {CategoryClient.class})
@EnableCaching //开启缓存支持
public class ProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(ProductApplication.class,args);
    }

}
- @Cacheable
位置:添加到方法和类上
作用:调用方法,查询是否有缓存,有直接走缓存,没有走方法,将方法的返回值进行缓存!
参数:
     value = String{} 配置缓存的 配置缓存‘分区’,相当于缓存的标示!
     key   = String   配置缓存的 ‘分区’下的具体表示,此处支持SpringEL表达式,动态命名
     cacheManager = String 选择配置类中的缓存配置对象beanname,不选走默认!
     condition = String 注解生效条件, 支持SpringEl表达式 例如: "#result != null"
                            结果不为null,进行缓存!
例如:
    @Cacheable(value = "product",key = "#root.methodName+" +
                                        "'-'+#productParamInteger.categoryID+" +
                                        "'-'+#productParamInteger.currentPage+" +
                                        "'-'+#productParamInteger.pageSize",cacheManager = "cacheManagerbean")
                                        
SpringEL表达式简单了解:
    
    #开头
    #root.method 被调用的方法
    #root.methodName 被调用的方法名称
    #root.target 调用方法的对象
    #root.args  方法的参数对象数组 支持[index]获取具体参数
    #result 方法执行后的结果
    #形参名  直接获取行参数名称 支持ognl向下继续读取
 
注意:
    缓存也分为curd
    所以,设计缓存value和key的时候,多思考,后期还需要进行删除和替换动作!   

- @CachePut
位置:添加到方法和类上
作用:不影响方法使用,将方法的返回值,进行指定的key更新,通常添加到修改方法上!
参数:
     value = String{} 配置缓存的 配置缓存‘分区’,相当于缓存的标示!
     key   = String   配置缓存的 ‘分区’下的具体表示,此处支持SpringEL表达式,动态命名
     cacheManager = String 选择配置类中的缓存配置对象beanname,不选走默认!
     condition = String 注解生效条件, 支持SpringEl表达式 例如: "#result != null"
                            结果不为null,进行更新!
例如:
    @CachePut(key = "#id", condition = "#result != null"),

- @CacheEvict
位置:添加到方法和类上
作用:不影响方法使用,将方法的返回值,进行指定的key失效,通常添加到删除方法上!
参数:
     value = String{} 配置缓存的 配置缓存‘分区’,相当于缓存的标示!
     key   = String   配置缓存的 ‘分区’下的具体表示,此处支持SpringEL表达式,动态命名
     cacheManager = String 选择配置类中的缓存配置对象beanname,不选走默认!
     condition = String 注解生效条件, 支持SpringEl表达式 例如: "#result != null"
                            结果不为null,进行失效!
例如:
   //单一失效
   @CacheEvict(value = "student", key = "'saveCache01'")
   //allEntries = true 删除分区所有的数据
   @CacheEvict(value = "list.product",allEntries = true)
   //多点失效
   @Caching(evict = {
            @CacheEvict(value = "student", key = "'saveCache01'"),
            @CacheEvict(value = "student", key = "'saveCache02'")
    }
- @Caching
位置:添加方法和类上
作用:多包涵注解,可以包含上面三个注解,用于复杂的缓存策略!
参数:
    Cacheable [] cacheable 配置多个缓存
    CachePut []  put 配置多个更新
    CacheEvict [] evict() 配置多个缓存

例如:
   订单模块
   订单支付,需要更新订单缓存,还要清空热门商品缓存!
  • 多服务缓存配置

  • 优化

    提取缓存配置和配置文件,减少代码冗余!

    • 导入依赖

      store-common-feign

<!-- 缓存依赖 -->
<!--spring-cache-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- redis连接池-->
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
- 导入配置类

  store-common-feign
/**
 * description: 缓存配置类 放置配置的方法,子模板继承和复用
 */
public class CacheConfiguration {


    //配置缓存manager
    @Bean
    @Primary  //同类型,多个bean,默认生效! 默认缓存时间1小时!  可以选择!
    public RedisCacheManager cacheManagerHour(RedisConnectionFactory redisConnectionFactory){

        RedisCacheConfiguration instanceConfig = instanceConfig(1 * 3600L);//缓存时间1小时

        //构建缓存对象
        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(instanceConfig)
                .transactionAware()
                .build();
    }

    //缓存一小时配置
    @Bean
    public RedisCacheManager cacheManagerDay(RedisConnectionFactory redisConnectionFactory){

        RedisCacheConfiguration instanceConfig = instanceConfig(24 * 3600L);//缓存时间1小时

        //构建缓存对象
        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(instanceConfig)
                .transactionAware()
                .build();
    }


    /**
     * 实例化具体的缓存配置!
     *    设置缓存方式JSON
     *    设置缓存时间 单位秒
     * @param ttl
     * @return
     */
    private RedisCacheConfiguration instanceConfig(Long ttl){

        //设置jackson序列化工具
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer
                = new Jackson2JsonRedisSerializer<Object>(Object.class);

        //常见jackson的对象映射器,并设置一些基本属性
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule(new JavaTimeModule());
        objectMapper.configure(MapperFeature.USE_ANNOTATIONS,false);
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);

        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

        return RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofSeconds(ttl)) //设置缓存时间
                .disableCachingNullValues()
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));
    }

}

- 声明缓存配置

  application-cache.yml

  指定环境配置变量,应用模块只需要激活,不用重复写!
spring:
  cache:
    type: redis
  redis:
    host: 124.221.70.206
    port: 6379
    jedis: # 设置Redis连接池
      pool:
        max-wait: 2000ms
        min-idle: 2
        max-idle: 8
        max-active: 10
- 生效服务激活cache配置

  使用缓存的模块和服务
spring:
  # 连接池配置
  datasource:
    url: jdbc:mysql://localhost:3306/store_product?useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
  profiles:
    active: cache  #激活store-common模块的缓存配置
- 生效服务即成配置类
@Configuration
public class ProductConfiguration extends CacheConfiguration {
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值