spring boot 最佳实践(六)--Spring Cache

在Spring Boot中对于缓存的支持,提供了一系列的自动化配置,使我们可以非常方便的使用缓存。

Hello Cache

spring boot为我们提供了开箱即用的缓存功能。只需要引入缓存包,并配置相应注解即可。默认使用ConcurrentMapCacheManager内存缓存。
1. 在pom.xml中引入cache依赖,添加如下内容:

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

2. 在有@Configuration注解的类中增加@EnableCaching注解开启缓存功能

@Configuration
@EnableCaching
public class CachingConfig {}

3. 在数据访问类中,增加缓存配置注解,如:

@Cacheable("dupulicateString")
public String dupulicate(String s){
        return s+s;
}

Spring Cache基本注解

  • @Cacheable 根据方法的请求参数对其结果进行缓存,建议尽量使用本方法。
  • @CachePut 根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是它每次都会触发真实方法的调用
  • @CachEvict 根据一定的条件对缓存进行清空
  • @CacheConfig 指定全局Cache配置。Spring 4.1之前需要每个方法上都指定,Spring 4.1时可以直接在类级别使用@CacheConfig指定。

@Cacheable注解主要参数,所有参数都是非必须参数:

  • value、cacheNames:用于指定缓存存储的集合名。如果类上没有配置@CacheConfig,则为必须配置的参数。
  • key:缓存对象key值,缺省按照函数的所有参数组合作为key值,支持SpEL表达式
  • condition:缓存对象的条件,只有满足表达式条件的内容才会被缓存,支持SpEL表达式
  • unless:缓存对象的条件,在函数被调用之后才做判断的,可以对result进行判断。
  • keyGenerator:用于指定key生成器,非必需,该参数与key是互斥的。
  • cacheManager:用于指定使用哪个缓存管理器
  • cacheResolver:用于指定使用那个缓存解析器

spring cache提供的SpEL上下文数据

名字位置示例描述
methodNameroot对象root.methodName当前被调用的方法名
methodroot对象root.method.name当前被调用的方法
targetroot对象root.target当前被调用的目标对象
targetClassroot对象root.targetClass当前被调用的目标对象类
argsroot对象root.args[0]当前被调用的方法的参数列表
cachesroot对象root.caches[0].name当前方法调用使用的缓存列表(如@Cacheable(value={“cache1”, “cache2”})),则有两个cache
argument name执行上下文user.id当前被调用的方法的参数,如findById(Long id),我们可以通过#id拿到参数
result执行上下文result方法执行后的返回值(仅当方法执行之后的判断有效,如‘unless’,’cache evict’的beforeInvocation=false)

使用redis做缓存

spring boot中使用redis做缓存只需要引入redis包即可。CacheAutoConfiguration会根据优先级自动替换掉默认的ConcurrentMapCacheManager内存缓存。

1. 在pom.xml中引入cache依赖,添加如下内容:

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

2. 配置RedisTemplate

RedisTemplate默认的序列化在终端查看redis数据时不方便阅读,建议调整为容易阅读的序列化方案。

@Bean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(JedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>();
        template.setConnectionFactory(redisConnectionFactory);
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
                Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        template.setDefaultSerializer(jackson2JsonRedisSerializer);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        template.setKeySerializer(stringRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

3. 添加超时时间
redis缓存默认永久有效,需要根据缓存名称设置超时时间。

@Bean
public CacheManagerCustomizer<RedisCacheManager> customizer(){
    return new CacheManagerCustomizer<RedisCacheManager>(){
            @Override
            public void customize(RedisCacheManager cacheManager) {
                //设置缓存过期时间
                Map<String, Long> expires=new HashMap<>();
                expires.put("wrapMap", 1000L);
                cacheManager.setExpires(expires);
              }
  };
}

混合使用不同的缓存

Spring Cache整个应用中默认只使用一种类型的缓存。但在使用了redis做缓存的情况下,我们依然需要将一些小数据放到内存里。从而提高性能并保证只有系统重启时才刷新数据。这时我们需要使用CompositeCacheManager做组合缓存。

1. 配置不同的缓存,并声明使用的缓存类型。

@Configuration
public class CompositeCacheConfig{
    @Bean(name = "simpleCacheManager")
    public ConcurrentMapCacheManager simpleCacheManager() {
        return  new ConcurrentMapCacheManager();
    }
    @Bean(name = "redisCacheManager")
    public RedisCacheManager redisCacheManager(CacheManagerCustomizer<RedisCacheManager> customizer,
            RedisTemplate<Object, Object> redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setUsePrefix(true);
        customizer.customize(cacheManager);
        return cacheManager;
    }
    @Bean
    public CompositeCacheManager cacheManager(ConcurrentMapCacheManager simpleCacheManager,RedisCacheManager redisCacheManager) {
        CompositeCacheManager cacheManager = new CompositeCacheManager();
        cacheManager.setFallbackToNoOpCache(false);

        List<CacheManager> cacheManagers = Lists.newArrayList();
        cacheManagers.add(simpleCacheManager);//顺序决定默认管理器
        cacheManagers.add(redisCacheManager);
        cacheManager.setCacheManagers(cacheManagers);
        return cacheManager;
    }
}

2. 实现CachingConfigurer

@Configuration
public class CompositeCachingConfigurer implements CachingConfigurer {

    @Autowired(required = false)
    private CompositeCacheManager cacheManager;

    @Override
    public CacheManager cacheManager() {
        return cacheManager;
    }

    @Bean
    @Override
    public CacheResolver cacheResolver() {
        return new SimpleCacheResolver(cacheManager);
    }

    @Override
    public KeyGenerator keyGenerator() {
        return new SimpleKeyGenerator();
    }

    @Override
    public CacheErrorHandler errorHandler() {
        return null;
    }

}

在方法中指定CacheManager

@Cacheable(value="wrapMap",cacheManager="simpleCacheManager")
public Map<String,String> wrap(String s)

https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-caching.html
http://jinnianshilongnian.iteye.com/blog/2001040

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值