Spring官方提供了Spring Cache在Spring Boot中的starter,所以要启动spring cache非常简便。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-cacheartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
@SpringBootApplication
@EnableCaching
@MapperScan("com.dongrui.study.spring_cache.mapper")
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
@Cacheable(value = "test", key = "'user:'+#conditions[id]+':info'",sync=true)
@Select("select * from tb_test_user t where t.id = #{id}")
Map<String, Object> getTestUser(Map<String, Object> conditions);
解析:
Cacheable注解可以标注在方法上,也可以标注在类上,当标注在方法上,是用来表明这个方法的返回值需要缓存,当标注在类上,则表明该类的所有方法都支持缓存;
value属性表示该缓存使用的命名域,其具体的作用方式是在缓存的key值前面拼接上_[namespace]::_,也可以使用cacheName属性,作用相同,value或cacheName是一个String[],意味着我们可以指定多个命名域,这时每个命名域都会缓存一份数据,在获取时只要任一命名域中查找到匹配的数据,就会从缓存中获取并返回;
key属性是用于设置该缓存的key值命名,上面的配置意为:‘user:‘字符串拼接上conditions中key为’id’所对应的value,然后在拼接上’:info’。如果不设置key,Spring Cache会根据参数自动生成一个key值,为了便于管理,还是尽量设置key值;
示例:test::user:1:info
sync属性是一个boolean值,默认为false,该属性为true时表明该key对应的缓存在被访问时需要同步进行,为false时允许异步访问;
使用jmeter进行压力测试,使用缓存与不使用缓存分别循环请求2000次,使用缓存比不使用缓存响应速度提升50%以上,该测试并不十分严谨,仅供参考;
@CacheEvict(value="test", key="'user:'+#params[id]+':info'")
@Update("update tb_test_user set name = #{newName} where id = #{id}")
int modifyTestCacheUser(Map<String, Object> params);
解析:
@CachePut(value = "test", key = "'user:'+#conditions[id]+':info'")
@Select("select * from tb_test_user t where t.id = #{id}")
Map<String, Object> getTestUser2(Map<String, Object> conditions);
解析:
从CacheType中可以看到Spring Cache自动配置支持的缓存类型,精简后的源码如下:
package org.springframework.boot.autoconfigure.cache;
public enum CacheType {
GENERIC,
JCACHE,
EHCACHE,
HAZELCAST,
INFINISPAN,
COUCHBASE,
REDIS,
CAFFEINE,
SIMPLE,
NONE
}
通过org.springframework.boot.autoconfigure.cache.CacheProperties我们可以知道,我们可以设置spring.cache.type属性来设置我们要使用的缓存,示例如下:
spring:
cache:
type: redis
如果上述缓存类型不能满足,那么还可以自定义cacheManager来使用我们希望使用的缓存,这里可以参考org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration中对cacheManager的实现,代码如下:
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory,
ResourceLoader resourceLoader) {
RedisCacheManagerBuilder builder = RedisCacheManager
.builder(redisConnectionFactory)
.cacheDefaults(determineConfiguration(resourceLoader.getClassLoader()));
List<String> cacheNames = this.cacheProperties.getCacheNames();
if (!cacheNames.isEmpty()) {
builder.initialCacheNames(new LinkedHashSet<>(cacheNames));
}
return this.customizerInvoker.customize(builder.build());
}
以及org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration中对cacheManager的实现,代码如下:
@Bean
public EhCacheCacheManager cacheManager(CacheManager ehCacheCacheManager) {
return this.customizers.customize(new EhCacheCacheManager(ehCacheCacheManager));
}
说明:这里仅做一个思路指引,不做深究,有兴趣或有具体需要,可以参照上述源码自己探索实现。
https://gitee.com/imdongrui/study-repo.git
仓库中的spring-cache工程