Spring Cache简介

Spring定义了CacheManager和Cache接口统一不同的缓存技术。其中CacheManager是Spring提供的各种缓存技术的抽象接口。而Cache接口包含缓存的各种操作,当然我们一般情况下不会直接操作Cache接口。

Spring针对不同的缓存技术,需要实现不同的cacheManager,Spring定义了如下的cacheManger实现:

|CacheManger| 描述|
|- |:—:|
|SimpleCacheManager |使用简单的Collection来存储缓存,主要用于测试
|ConcurrentMapCacheManager| 使用ConcurrentMap作为缓存技术(默认)
|NoOpCacheManager |测试用
|EhCacheCacheManager |使用Ehcache作为缓存技术,以前在HIbernate的时候经常用
|GuavaCacheManager |使用google guava的GuavaCache作为缓存技术
|HazelcastCacheManager |使用Hazelcast作为缓存技术
|JCacheCacheManager |使用JCache标准的实现作为缓存技术,如Apache Commons JCS
|RedisCacheManager |使用Redis作为缓存技术

常规的SpringBoot已经为我们自动配置了EhCache、Collection、Guava、ConcurrentMap等缓存,默认使用SimpleCacheConfiguration,即使用ConcurrentMapCacheManager。

SpringBoot整合EHCache

pom.xml引入spring-boot-starter-cache和ehcache

1
2
3
4
5
6
7
8
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>

配置ehcache.xml

1
2
3
4
5
6
7
8
9
10
11
12
<?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">
<diskStore path="java.io.tmpdir/Tmp_EhCache"/>
<defaultCache eternal="false" maxElementsInMemory="1000"
overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/>
<cache name="user" eternal="false" maxElementsInMemory="10000"
overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
timeToLiveSeconds="0" memoryStoreEvictionPolicy="LFU"/>
</ehcache>

需要说明的是,这里maxElementsInMemory属性是必须的。

配置application.yml

1
2
3
4
5
spring:
cache:
type: ehcache
ehcache:
config: classpath:config/ehcache.xml

如果ehcache.xml在/resources下,则不用配置spring.cache.ehcache.config

Spring Boot启动类增加@EnableCaching开启缓存

1
2
3
4
5
6
7
@SpringBootApplication
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

缓存注解说明

  • @CacheConfig(cacheNames = {“lemonCache”}):设置了ehcache的名称,这个名称就是ehcache.xml内的名称;
  • @Cacheable:应用到读取数据的方法上,即可缓存的方法,如查找方法:先从缓存中读取,如果没有再调 用方法获取数据,然后把数据添加到缓存中,适用于查找;
  • @CachePut:主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用。适用于更新和插入;
  • @CacheEvict:主要针对方法配置,能够根据一定的条件对缓存进行清空。适用于删除。

示例:

1
2
3
4
5
6
7
8
9
10
11
@CacheConfig(cacheNames = "user")
public class UserServiceImpl implements UserService {
@Cacheable
public UserDO get(String username) {
Map<String,Object> map = new HashedMap(1);
map.put("username",username);
UserDO user = list(map).get(0);
return user;
}

}

与Shiro结合导致缓存不生效的问题

基本确定是shiro框架与spring框架的BeanFactory有所冲突,导致注入shiro框架的类不能被spring正确初始化。

在我们自定义的Shiro Realm中注入的Service增加@Lazy。

参考:https://www.cnblogs.com/yueshutong/p/9381558.html

参考:https://www.cnblogs.com/yueshutong/p/9381540.html

Spring Cache Key的生成使用Spring EL表达式,自定义生成策略参考:https://www.jianshu.com/p/2a584aaafad3

Spring Cache章节:https://docs.spring.io/spring/docs/5.0.8.RELEASE/spring-framework-reference/integration.html#cache
Spring Boot Cache章节:https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/html/boot-features-caching.html