简介
本文介绍SpringBoot缓存的用法。
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
请先
!