[spring]cache数据缓存

        缓存可以存储经常会用到的数据,spring对缓存提供了声明式的支持,能够与多种流行的缓存实现进行集成。spring使用缓存流程如下:

  1. 使用@EnableCaching启用缓存。
  2. 配置缓存管理器
  3. 为需要缓存的方法添加相关注解。

启用缓存

@EnableCaching
@Configuration
public class CacheConfig {

//缓存配置

}

配置缓存管理器

缓存管理器是spring缓存抽象的核心,它能够与多个流行的缓存实现进行集成。

spring3.1内置了5个缓存管理器

  1. SimpleCacheManager
  2. NoOpCacheManager
  3. ConcurrentMapCacheManager
  4. CompositeCacheManager
  5. EhChcheCaheManager

Spring3.2引入一个新的管理器,可基于JCache(JSR-107)的缓存提供商。Spring Data又提供了两个缓存管理器。

  1. RedisCacheManager(来自于Spring Data Redis项目)
  2. GemfireCacheManager(来自于Spring Data GemFire项目)

配置Redis缓存管理器

RedisCacheManager 会与Redis服务器协作,并通过 RedisTemplate 将缓存条目存储到 Redis 中。

配置RedisConnectionFactory

使用RedisTemplate前需要先声明RedisConnectionFactory实现类的bean。Spring Data Redis为四种Redis客户端实现提供了连接工厂:
  1. JedisConnectionFactory
  2. JredisConnectionFactory
  3. LettuceConnectionFactory
  4. SrpConnectionFactory

JedisConnectionFactory为例,装配代码如下:

@Bean
public RedisConnectionFactory redisCF() {
  JedisConnectionFactory cf = new LettuceConnectionFactory();
  cf.setHostName("redis-server");
  cf.setPort(7379);
  cf.setPassword("foobared");
  return cf;
}

如果使用其它链接工厂,只需要替换即可。

配置RedisTemplate

Spring Data Redis 提供了两个模板:
  1. RedisTemplate
  2. StringRedisTemplate
RedisTemplate可以简化redis的访问,方便我们持久化各种类型的key及value。
StringRedisTemplate 扩展了 RedisTemplate ,只关注key和value为 String 类型。
 
声明RedisTemplate 的简单 @Bean 方法:
@Bean
public RedisTemplate<String, Product>
                            redisTemplate(RedisConnectionFactory cf) {
  RedisTemplate<String, Product> redis =
      new RedisTemplate<String, Product>();
  redis.setConnectionFactory(cf);
  return redis;
}
声明 StringRedisTemplate bean @Bean 方法:
@Bean
public StringRedisTemplate
                      stringRedisTemplate(RedisConnectionFactory cf) {
  return new StringRedisTemplate(cf);
}

RedisTemplate API:

方法

子API接口

Description

opsForValue()ValueOperations<K, V>Operations for working with entries having simple values
opsForList()ListOperations<K, V>Operations for working with entries having list values
opsForSet()SetOperations<K, V>Operations for working with entries having set values
opsForZSet()ZSetOperations<K, V>Operations for working with entries having ZSet (sorted set) values
opsForHash()HashOperations<K, HK, HV>Operations for working with entries having hash values
boundValueOps(K)BoundValueOperations<K,V>Operations for working with simple values bound to a given key
boundListOps(K)BoundListOperations<K,V>Operations for working with list values bound to a given key
boundSetOps(K)BoundSetOperations<K,V>Operations for working with set values bound to a given key
boundZSet(K)BoundZSetOperations<K,V>Operations for working with ZSet (sorted set) values bound to a given key
boundHashOps(K)BoundHashOperations<K,V>Operations for working with hash values bound to a given key

设置key和value序列化器

当数据保存到redis中时,key和value都会使用序列化器进行序列化。Spring data redis提供了多个序列化器:

  • GenericToStringSerializer 使用Spring转换服务进行序列化
  • JacksonJsonRedisSerializer 使用Jackson 1,将对象序列化为JSON
  • Jackson2JsonRedisSerializer 使用Jackson 2,将对象序列化为JSON
  • JdkSerializationRedisSerializer 使用Java序列化
  • OxmSerializer —使用Spring O/X映射的编排器和解排器(marshaler和unmarshaler)实 现序列化,用于XML序列化
  • StringRedisSerializer 序列化String类型的keyvalue
这些序列化器都实现了 RedisSerializer 接口,如果其中没有符合需求的序列化器,可以自行创建。
RedisTemplate 默认使用 JdkSerializationRedisSerializer。
StringRedisTemplate 默认使用StringRedisSerializer。
 
设置序列化器
@Bean
public RedisTemplate<String, Product>
       redisTemplate(RedisConnectionFactory cf) {
  RedisTemplate<String, Product> redis =
      new RedisTemplate<String, Product>();
  redis.setConnectionFactory(cf);
  redis.setKeySerializer(new StringRedisSerializer());
  redis.setValueSerializer(
      new Jackson2JsonRedisSerializer<Product>(Product.class));
  return redis;
}
以上内容简单描述了RedisTemplate的配置。下面将介绍redis的缓存管理器的配置。
package com.myapp;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.jedis
                                      .JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;

@Configuration
@EnableCaching
public class CachingConfig {

  @Bean
  public CacheManager cacheManager(RedisTemplate redisTemplate) {
    //redis缓存管理器
    return new RedisCacheManager(redisTemplate);	
   }

  @Bean
  public JedisConnectionFactory redisConnectionFactory() {	
    //连接工厂
    JedisConnectionFactory jedisConnectionFactory =
           new JedisConnectionFactory();
   jedisConnectionFactory.afterPropertiesSet();
   return jedisConnectionFactory;
  }

  @Bean
  public RedisTemplate<String, String> redisTemplate(	
           RedisConnectionFactory redisCF) {
    //redisTemplate bean
    RedisTemplate<String, String> redisTemplate =
            new RedisTemplate<String, String>();
    redisTemplate.setConnectionFactory(redisCF);
    redisTemplate.afterPropertiesSet();
    return redisTemplate;
  }

}

配置多个缓存管理器

可使用Spring的 CompositeCacheManager配置多个缓存管理器, CompositeCacheManager要通过一个或更多的缓存管理器来进行配置,它会迭代这些缓存管理器,以查找之前所缓存的值。
@Bean
public CacheManager cacheManager(
      net.sf.ehcache.CacheManager cm,
      javax.cache.CacheManager jcm) {

  CompositeCacheManager cacheManager = new CompositeCacheManager();	
  List<CacheManager> managers = new ArrayList<CacheManager>();
  managers.add(new JCacheCacheManager(jcm));
  managers.add(new EhCacheCacheManager(cm))
  managers.add(new RedisCacheManager(redisTemplate()));
  cacheManager.setCacheManagers(managers);	
  return cacheManager;
}

当查找缓存时,系统将依次通过JCacheCacheManager、EhCacheCacheManager、RedisCacheManager查找。

 

缓存注解

Spring 提供了如下四个注解来声明缓存规则:

注解

描述

@Cacheable
表明 Spring在调用方法之前,首先应该在缓存中查找方法的返回值。如果这个值能够找到,就会返回缓存的值(不会调用方法)。否则的话,这个方法就会被调用,返回值会放到缓存之中(只能应用在返回值为非void的方法上)
@CachePut
表明 Spring应该将方法的返回值放到缓存中。在方法的调用前并不会检查缓存,方法始终都会被调用(只能应用在返回值为非void的方法上)
@CacheEvict
表明 Spring 应该在缓存中清除一个或多个数据(可以应用在返回值为void的方法上)
@Caching
这是一个分组的注解,能够同时应用多个其他的缓存注解
@CacheConfig 统一配置本类的缓存注解的属性,在类上面统一定义缓存的名字,方法上面就不用标注了,当标记在一个类上时则表示该类所有的方法都是支持缓存的

填充缓存

可以使用@Cacheable和CachePut进行缓存填充,需注意两者差别。

@Cacheable:表明Spring在调用方法之前,首先应该在缓存中查找方法的返回值。如果这个值能够找到,就会返回缓存的值(不会调用方法)。否则的话,这个方法就会被调用,返回值会放到缓存之中

@CachePut:表明Spring应该将方法的返回值放到缓存中。在方法的调用前并不会检查缓存,方法始终都会被调用

@Cacheable @CachePut 有一些属性是共有的:

属性

类型

描述

value、cacheNamesString[]要使用的缓存名称
conditionString
SpEL 表达式,如果得到的值是 false 的话,不会将缓存应用到方法调用上
keyString
SpEL 表达式,用来计算自定义的缓存 key
unlessString
SpEL 表达式,如果得到的值是 true 的话,返回值不会放到缓存之中
keyGenerator 用于指定key生成器,非必需。若需要指定一个自定义的key生成器,我们需要去实现org.springframework.cache.interceptor.KeyGenerator接口,并使用该参数来指定。需要注意的是:该参数与key是互斥的
cacheManager 用于指定使用哪个缓存管理器,非必需。只有当有多个时才需要使用
cacheResolver 用于指定使用那个缓存解析器,非必需。需通过org.springframework.cache.interceptor.CacheResolver接口来实现自己的缓存解析器,并用该参数指定。

当使用Spel表达式时,spring定义了一些供使用的元数据,如下:

表达式

描述

#root.args
传递给缓存方法的参数,形式为数组
#root.caches
该方法执行时所对应的缓存,形式为数组
#root.target
目标对象
#root.targetClass
目标对象的类,是 #root.target.class 的简写形式
#root.method
缓存方法
#root.methodName
缓存方法的名字,是 #root.method.name 的简写形式
#result
方法调用的返回值(不能用在 @Cacheable 注解上)
#Argument
任意的方法参数名(如 #argName )或参数索引(如 #a0 #p0

unless和condition的差别

unless 属性只能阻止将对象放进缓存,但是在这个方法调用的时候,依然会去缓存中进行查找,如果找到了匹配的值,就会返回找到的值(决定结果要不要存入缓存)。
如果 condition 的表达 式计算结果为false ,那么在这个方法调用的过程中,缓存是被禁用的。就是说,不会去缓存进行查找,同时返回值也不会放进缓存中。(决定缓存注解生不生效:调用之前要不要查缓存,调用成功之后要不要放缓存)

 

移除缓存

移除缓存使用@CacheEvict注解,属性如下:

Attribute

Type

Description

value、cacheNamesString[]要使用的缓存名称
keyString
SpEL 表达式,用来计算自定义的缓存 key
conditionString
SpEL 表达式,如果得到的值是 false 的话,缓存不会应用到方法调用上
allEntriesboolean
如果为 true 的话,特定缓存的所有条目都会被移除掉
beforeInvocationboolean
如果为 true 的话,在方法调用之前移除条目。如果为 false (默认值)的话,在方
法成功调用之后再移除条目
 

注意

  1. 同一个类的a方法调用b方法,注解不生效。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值