Spring Boot 缓存实现

本文主要内容:

1. Spring 缓存抽象定义及相关概念

2. @Cacheable,@CachePut, @CacheEvict, @CacheConfig使用

3.基于Redis的缓存实现

1. Spring 缓存抽象定义及相关概念

1. Spring从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来统一不同的缓存技术;并支持使用Java
Caching(JSR-107)注解简化我们进行缓存开发

JSR-107中定义了5个核心接口,分别是CachingProvider(缓存提供者)、CacheManager(缓存管理者)、Cache(缓存)、Entry(缓存键值对)和Expiry(缓存时效)

Spring Cache只负责抽象层,Cache 实现有:RedisCache、EhCacheCache、
ConcurrentMapCache等

在SpringBoot自动装配过程中,创建了CacheMamager对象,默认情况下使用SimpleCacheConfiguration 向IOC容器中注入ConcurrentMapCacheManager (CacheMamager)

Cache底层数据结构为 ConcurrentHashMap

2. @Cacheable,@CachePut, @CacheEvict, @CacheConfig使用

1. 开启缓存 @EnableCaching

.....
@EnableCaching
public class MySpringBootDemoApplication {

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

}

 2, @Cacheable,@CachePut, @CacheEvict

@Cacheable将方法运行的结果进行缓存,后期再获取相同的数据时,直接从缓存中获取,不再调用方法

属性信息包含

***** 既满足condition又满足unless条件的也不进行缓存
**** 使用异步模式进行缓存时(sync=true):unless条件将不被支持

@CachePut 调用方法,之后将方法的结果放入缓存  (可用于 更新操作时,更新缓存数据)

@CacheEvict 缓存清除,清除缓存时要指明缓存的名字和key( key默认为参数的值 )

 ***** 在使用过程中,@CachePut 和 @CacheEvict 修改和删除缓存,要保证cacheNames和key能对应到相应的缓存信息;

如下 

@Cacheable(cacheNames = "user", key = "#id")
public User findById(Integer id) {
   return userMapper.findById(id);
}

@CachePut(cacheNames = "user", key = "#user.id")
public User update(User user) {
   userMapper.update(user);
   return user;
}

@CacheEvict(cacheNames = "user", key = "#id")
public void delete(Integer id) {
   userMapper.delete(id);
}

附:常用spEL表达式

 3. @CacheConfig 标注在类上,抽取缓存相关注解的公共配置,可抽取的公共配置有缓存名字、主键生成器等(如注解中的属性所示)

包含属性 cacheNames   keyGenerator  cacheManager  cacheResolver

@CacheConfig(cacheNames = "user")
public class UserServiceImpl implements UserService {
       .......

   @Cacheable( key = "#id")
   public User findById(Integer id) {
      return userMapper.findById(id);
   }

   @CachePut( key = "#user.id")
   public User update(User user) {
      userMapper.update(user);
      return user;
   }


   @CacheEvict(key = "#id")
   public void delete(Integer id) {
      userMapper.delete(id);
   }
}

 

3.基于Redis的缓存实现 

1. 添加spring-boot-redis-starter依赖

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

2.  实体类需要 可序列化

public class User implements Serializable {

3. redis配置

spring.redis.host=127.0.0.1
spring.redis.database=1

参考其配置类

@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {

   /**
    * Database index used by the connection factory.
    */
   private int database = 0;

   /**
    * Connection URL. Overrides host, port, and password. User is ignored. Example:
    * redis://user:password@example.com:6379
    */
   private String url;

   /**
    * Redis server host.
    */
   private String host = "localhost";

   /**
    * Login password of the redis server.
    */
   private String password;

   /**
    * Redis server port.
    */
   private int port = 6379;

   /**
    * Whether to enable SSL support.
    */
   private boolean ssl;

   /**
    * Connection timeout.
    */
   private Duration timeout;

   /**
    * Client name to be set on connections with CLIENT SETNAME.
    */
   private String clientName;

   private Sentinel sentinel;

   private Cluster cluster;

        ................

4.自定义RedisCacheManager,设置序列化方式为格式 (SpringBoot默认采用的是JDK的对象序列化方式)

@Configuration
public class RedisConfig {
   @Bean
   public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
      // 分别创建String和JSON格式序列化对象,对缓存数据key和value进行转换
      RedisSerializer<String> strSerializer = new StringRedisSerializer();
      Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
      // 解决查询缓存转换异常的问题
      ObjectMapper om = new ObjectMapper();
      om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
      om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
      jacksonSeial.setObjectMapper(om);
      // 定制缓存数据序列化方式及时效
      RedisCacheConfiguration config = RedisCacheConfiguration
            .defaultCacheConfig()
            .entryTtl(Duration.ofDays(1))
            // 设置key的序列化方式
            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(strSerializer))
            // 设置value的序列化方式
            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jacksonSeial)) 
            .disableCachingNullValues();
      RedisCacheManager cacheManager = RedisCacheManager.builder(redisConnectionFactory).cacheDefaults(config).build();
      return cacheManager;
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值