Spring自带的代码级缓存方案,支持透明的添加缓存到Spring项目中,不需要复杂的代码支持。需结合其他缓存中间件,例如Redis,Ehcache、Mamercache等。
官方文档:https://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html
Spring cache基本原理
和 spring 的事务管理类似,spring cache 的关键原理就是 spring AOP,通过 spring AOP,其实现了在方法调用前、调用后获取方法的入参和返回值,进而实现了缓存的逻辑。
在Spring Boot应用中使用Spring Cache需要在@SpringBootConfiguration
标注的Class上添加@EnableCaching
,这样就启用了Spring Cache。Spring Boot将根据Classpath下提供的Spring Cache实现类选择合适的实现者进行自动配置,支持的实现有基于Ehcache的实现、基于Redis的实现等,详情可参考org.springframework.boot.autoconfigure.cache.CacheConfiguration
的源码。如果没有找到,则会使用基于ConcurrentMap的实现。
关键类:
CacheManager缓存管理器
它的实现部分是由RedisCacheManager实现。在这里配置缓存策略,过期时间、缓存地址等。
缓存注解
Spring Cache提供的注解:
@Cacheable 触发缓存,一般用于查询操作
-
value、cacheNames
缓存的名称,在 spring 配置文件中定义,必须指定至少一个
例如: @Cacheable(value=”mycache”) @Cacheable(value={”cache1”,”cache2”} -
key
缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
例如: @Cacheable(value=”testcache”,key=”#userName”) -
condition
缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存
例如:@Cacheable(value=”testcache”,condition=”#userName.length()>2”)
@CachePut 更新缓存,一般用于更新和插入操作,每次都会请求db
@CacheEvic 移除缓存
-
value
缓存的名称,在 spring 配置文件中定义,必须指定至少一个
例如: @CacheEvict(value=”my cache”) -
key
缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合
例如: @CacheEvict(value=”testcache”,key=”#userName”) -
condition
缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存
例如: @CacheEvict(value=”testcache”,condition=”#userName.length()>2”) -
allEntries
是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存
例如: @CachEvict(value=”testcache”,allEntries=true) -
beforeInvocation
是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存
例如: @CachEvict(value=”testcache”,beforeInvocation=true)
CacheConfig
- 类级别的注解方式
缓存数据的选取
简单概括三个标准:
- 数据量不大
- 访问频率高
- 数据更改频率低
Spring-cache + Redis
Spring cache +redis的好处显而易见。既可以很方便的缓存对象(Spring cache的代码),同时用来缓存的内存的是redis(NoSQL数据库、缓存服务器),不会消耗JVM的内存,提升了性能。
关键Jar包
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
Spring
比较复杂,主流使用Spring Boot替代。
Spring Boot
导入spring-boot-starter-data-redis
时,自动注册相关Bean,自己的项目中修改配置,直接注入使用即可。
application.properties
# redis
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.timeout=0
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringcacheApplicationTests {
@Autowired
StringRedisTemplate redisTemplate;
@Test
public void contextLoads() {
Assert.assertNotNull(redisTemplate);
redisTemplate.opsForValue().set("hello", "world");
String value = redisTemplate.opsForValue().get("hello");
log.info("value = " + value);
redisTemplate.delete("hello");
value = redisTemplate.opsForValue().get("hello");
log.info("value = " + value);
}
}