简介
说明
Spring从3.1开始通过以下方法支持缓存:
- 定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来统一不同的缓存技术;
- CacheManager是Spring提供的各种缓存技术抽象接口,内部使用Cache接口进行缓存的增删改查操作,我们一般不会直接和Cache打交道。
- 支持使用JCache(JSR-107)注解简化我们开发;
缓存的逻辑
每次调用需要缓存功能的方法时,Spring会检查检查指定参数的指定的目标方法是否已经被调用过;
- 如果有:直接从缓存中获取方法调用后的结果
- 如果没有:调用方法并缓存结果后返回给用户。下次调用直接从缓存中获取。
Cache的实现方式
要使用Spring Boot的缓存功能,需要提供一个缓存的具体实现。
可配置属性spring.cache.type强制指定缓存的实现。若不指定,则按顺序去侦测。
Spring Boot根据下面的顺序去侦测缓存实现:
- Generic
- JCache (JSR-107)
- EhCache 2.x
- Hazelcast
- Infinispan
- Redis
- Guava
- Simple
CacheManager实现类
针对不同的缓存技术,Spring有不同的CacheManager实现类,定义如下表:
CacheManager | 描述 |
JCacheCacheManager | 使用JCache(JSR-107)标准的实现作为缓存技术,比如Apache Commons JCS |
EhCacheCacheManager | 使用EhCache作为缓存技术 |
RedisCacheManager | 使用Redis作为缓存技术 |
GuavaCacheManager | 使用Google Guava的GuavaCache作为缓存技术 |
ConcurrentMapCacheManager | 使用ConcurrentHashMap作为缓存技术(默认的方式) |
SimpleCacheManager | 使用Collection作为缓存技术。主要用于测试 |
NoOpCacheManager | 用于测试目的,事实上它并不缓存任何数据。 |
使用任意一个实现的CacheManager的时候,需要注册实现Bean:
// EhCache的配置
public EhCacheCacheManager cacheManager(CacheManager cacheManager) {
return new EhCacheCacheManager(cacheManager);
}
使用
1.启用缓存功能
@EnableCaching:开启缓存功能。
package com.example.cache;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class SpringbootApplication{
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
2.指定缓存方式
见下方“指定缓存方式”
指定缓存方式
Redis
1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
引入此依赖之后,SpringBoot会自动配置RedisCacheManager这个Bean(CacheManager的实现类),同时还会配置RedisTemplate这个Bean。
当然,也可以手动提供bean,这样可以进行自定义的配置,覆盖默认配置:
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
// 自定义缓存key生成策略
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, java.lang.reflect.Method method, Object... params) {
StringBuffer sb = new StringBuffer();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
}
};
}
// 缓存管理器
@Bean
public CacheManager cacheManager(@SuppressWarnings("rawtypes") RedisTemplate redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
// 设置缓存过期时间(秒)
cacheManager.setDefaultExpiration(3600);
return cacheManager;
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
setSerializer(template);// 设置序列化工具
template.afterPropertiesSet();
return template;
}
private void setSerializer(StringRedisTemplate template) {
@SuppressWarnings({ "rawtypes", "unchecked" })
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
}
}
2.配置Redis信息
application.yml
spring:
redis:
# Redis数据库索引(默认为0)
database: 0
# Redis服务器地址
host: localhost
# Redis服务器连接端口
port: 6379
# Redis服务器密码
password: 123456
pool:
# 连接池最大连接数(使用负值表示没有限制)
max-active: 8
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1
# 连接池中的最大空闲连接
max-idle: 8
# 连接池中的最小空闲连接
min-idle: 0
# 连接超时时间(毫秒)
timeout: 0
Guava
1.引入依赖
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
引入此依赖之后,SpringBoot会为我们自动配置GuavaCacheManager这个Bean。
Ehcache
1.引入依赖
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcahe</artifactId>
</dependency>
2.配置文件(可以不配置)
application.yml
默认就是下边这个路径,ehcache.xml必须有。
spring:
cache:
ehcache:
config: classpath:/ehcache.xml
3.ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false" monitoring="autodetect"
dynamicConfig="true">
<diskStore path="java.io.tmpdir/ehcache"/>
<defaultCache
maxElementsInMemory="50000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="true"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
/>
<cache name="authorizationCache"
maxEntriesLocalHeap="2000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="false"
statistics="true">
</cache>
</ehcache>
diskStore节点
磁盘存储:将缓存中暂时不使用的对象,转移到硬盘,类似于Windows系统的虚拟内存 path:指定在硬盘上存储对象的路径 path可以配置的目录有: user.home(用户的家目录) user.dir(用户当前的工作目录) java.io.tmpdir(默认的临时目录) ehcache.disk.store.dir(ehcache的配置目录) 绝对路径(如:d:\\ehcache) 查看路径方法:String tmpDir = System.getProperty("java.io.tmpdir");
defaultCache
默认的缓存配置信息,如果不加特殊说明,则所有对象按照此配置项处理。
- axElementsInMemory:设置了缓存的上限,最多存储多少个记录对象
- eternal:代表对象是否永不过期 (指定true则下面两项配置需为0无限期)
- timeToIdleSeconds:最大的发呆时间 /秒
- timeToLiveSeconds;最大的存活时间 /秒
- overflowToDisk:是否允许对象被写入到磁盘
说明:示例中的配置自缓存建立起600秒(10分钟)有效 。 在有效的600秒(10分钟)内,如果连续120秒(2分钟)未访问缓存,则缓存失效。 就算有访问,也只会存活600秒。
ConcurrentHashMap
Spring boot默认使用ConcurrentMapCacheManager来管理缓存(内部使用ConcurrentHashMap)。
所以,只在启动类加注解即可:@EnableCaching