缓存介绍
Spring3.1之后引入了基于注释(annotation)的缓存(cache)技术,它本质上不是一个具体的缓存实现方案(如EHCache 或者Redis),而是一个对缓存使用的抽象,通过在既有代码中添加少量它定义的各种annotation,即能够达到缓存方法的返回对象的效果。
Spring的缓存技术还具备相当的灵活性,不仅能够使用 SpEL(Spring Expression Language)来定义缓存的key和各种condition,还提供开箱即用的缓存临时存储方案,也支持和主流的专业缓存,例如Redis、EHCache集成。
Spring Cache位于spring-content中,如下图
Spring Cache涉及主要类
Spring定义了Cache和CacheManager两个基础接口类。
Cache
Cache
接口提供了其他缓存技术实现的规范,包括缓存的各种操作,增加、删除、获取缓存等。Cache默认实现缓存如下,其中Ehcache
、RedisCache
都为流行的Cache实现方法。
CacheManager
CacheManager
是Spring提供的各种缓存技术抽象接口,通过它管理Spring框架内部默认实现的CacheManager,Spring框架内部默认实现的CacheManager如下
CacheResolver
CacheResolver
解析器,用于根据实际情况来动态解析使用哪个Cache。
KeyGenerator
KeyGenerator
当使用注解时,默认key的生成规则。
Spring Cache主要的注解
@Cacheable
用于读取缓存的方法上,先从缓存中读取数据,如果没有再调用具体方法获取数据,然后将数据添加到缓存中。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Cacheable {
//cacheNames的别名
@AliasFor("cacheNames")
String[] value() default {};
//方法调用的结果存储时的cache名字
@AliasFor("value")
String[] cacheNames() default {};
//缓存的键值名称,支持SpEL
String key() default "";
//key的生成策略
String keyGenerator() default "";
//cache管理器,不指定使用默认
String cacheManager() default "";
//cache解析器,不指定使用默认
String cacheResolver() default "";
//满足何种条件才能被缓存,支持SpEL
String condition() default "";
//满足哪些结果不加入缓存
String unless() default "";
//是否同步读取缓存,更新缓存
boolean sync() default false;
}
例子:
@Cacheable(value = "user", key = "#id",condition = "#id.length()>0",unless = "#id==null")
public User findById(String id) {
return userDao.findById(id).orElseGet(User::new);
}
@CachePut
用于保存或者更新方法上,调用方法时将相应数据存入缓存中。
例子:
@CachePut(value = "user", key = "#user.id")
@Transactional
public User update(User user) {
return userDao.save(user);
}
@CacheEvict
用于删除方法上,删除对应缓存。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CacheEvict {
...
//是否删除所有实体对象
boolean allEntries() default false;
//是否在方法调用之前执行,默认在调用方法执行成功后删除缓存。
boolean beforeInvocation() default false;
例子:
@CacheEvict(value = "user")
public void delete() {
...
}
@Caching
组合使用Cache注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Caching {
Cacheable[] cacheable() default {};
CachePut[] put() default {};
CacheEvict[] evict() default {};
}
@CacheConfig
全局Cache配置,自定义cache时需在方法上指定此注解。
@EnableCaching
开启Spring Cache的默认配置,启动缓存需要在项目中添加此注解。
Spring Boot集成
redis
支持分布式缓存,默认使用Luttuce客户端,也可采用Jedis。
引入依赖
pom.xml
<!--缓存-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!--redis实现-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置文件
application.yml
单机模式配置
spring:
application:
name: coding-cache-redis
# redis配置
redis:
host: localhost
port: 6379
password: 1111
database: 0
# 启动缓存类型
cache:
type: redis
哨兵模式配置
spring:
application:
name: coding-cache-redis
redis:
sentinel:
master: mymaster
nodes: 192.168.81.10:26375,192.168.81.11:26376,192.168.81.12:26377
database: 3
password: 1111
# 启动缓存类型
cache:
type: redis
集群模式配置
spring:
application:
name: coding-cache-redis
redis:
database: 3
password: 1111
cluster:
#代表redis多个节点的ip与端口号,多个节点需要使用“,”隔开。
nodes: 192.168.81.10:26375,192.168.81.11:26376,192.168.81.12:26377
#最大重定向次数
max-redirects: 2
# 启动缓存类型
cache:
type: redis
启动缓存
在Application启动类中使用@EnableCaching
注解启用缓存
@EnableCaching
@SpringBootApplication
public class CodingCacheRedisApplication {
public static void main(String[] args) {
SpringApplication.run(CodingCacheRedisApplication.class, args);
}
}
具体操作
@Service
@CacheConfig(cacheNames = "user")
public class UserService {
@Autowired
private UserDao userDao;
@Cacheable
@Transactional
public User save(User user) {
return userDao.save(user);
}
// 缓存更新
@CachePut(key = "#user.id")
@Transactional
public User update(User user) {
return userDao.save(user);
}
// 缓存保存
@Cacheable(key = "#id", condition = "#id.length()>0", unless = "#id==null")
public User findById(String id) {
return userDao.findById(id).orElseGet(User::new);
}
//缓存删除
@CacheEvict
@Transactional
public void delete(String id) {
userDao.deleteById(id);
}
}
Ehcache
EhCache 是一个纯 Java 的进程内缓存框架,具有快速、精干等特点,是 Hibernate 中默认的 CacheProvider 。
引入依赖
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
配置文件
application.yml
spring:
application:
name: coding-cache-redis
# redis配置
redis:
host: localhost
port: 6379
password: 1111
database: 0
# 启动缓存类型
cache:
type: ehcache
在resources下添加ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<!--硬盘上缓存存储位置 -->
<!--user.home 用户home目录 -->
<!--user.dir 用户当前工作目录-->
<!--java.io.tmpdir默认临时目录-->
<defaultCache
eternal="false"
maxEntriesLocalHeap="2000"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false" />
<!-- user 缓存 -->
<!-- name:缓存名 -->
<!-- maxElementsInMemory:最大缓存 key 数量 -->
<!-- timeToLiveSeconds:缓存过期时长,单位:秒 -->
<!-- memoryStoreEvictionPolicy:缓存淘汰策略 -->
<cache name="user"
maxElementsInMemory="1000"
timeToLiveSeconds="60"
memoryStoreEvictionPolicy="LRU"/>
</cache>
</ehcache>
启动缓存
在Application启动类中使用@EnableCaching
注解启用缓存
@EnableCaching
@SpringBootApplication
public class CodingCacheRedisApplication {
public static void main(String[] args) {
SpringApplication.run(CodingCacheRedisApplication.class, args);
}
}
具体操作
同redis