前提;下列配置是基于springboot2.0以上版本实现的,springboot2.0以下版本见下一篇文档。
首先引入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
在application.yml(application.properties配置文件省略)
spring:
redis:
host: localhost
password:
port: 6379
主方法上加缓存注解:
package cn.cache.testcache;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching
public class TestcacheApplication {
public static void main(String[] args) {
SpringApplication.run(TestcacheApplication.class, args);
}
}
设置缓存的配置文件:
package cn.cache.testcache.shuai;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import java.time.Duration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@Configuration
public class CacheConfig extends CachingConfigurerSupport {
/**
* 自定义key.
* 此方法将会根据类名+方法名+所有参数的值生成唯一的一个key
*/
@Bean
@Override
public KeyGenerator keyGenerator() {
return (o, method, objects) -> {
StringBuilder sb = new StringBuilder();
sb.append(o.getClass().getName());
sb.append(":");
sb.append(method.getName());
for (Object obj : objects) {
sb.append(":");
sb.append(obj.toString());
}
return sb.toString();
};
}
//缓存管理器
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
// 生成一个默认配置,通过config对象即可对缓存进行自定义配置
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
// 设置缓存的默认过期时间,也是使用Duration设置
// config = config.entryTtl(Duration.ofMinutes(10))
// .disableCachingNullValues(); // 不缓存空值
// 设置一个初始化的缓存空间set集合
Set<String> cacheNames = new HashSet<>();
cacheNames.add("my-redis-cache1");
cacheNames.add("my-redis-cache2");
// 对每个缓存空间应用不同的配置
Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
// 通过Duration可以自己实现以什么时间为单位
configMap.put("my-redis-cache1", config.entryTtl(Duration.ofMinutes(1)));
configMap.put("my-redis-cache2", config.entryTtl(Duration.ofSeconds(20)));
// 使用自定义的缓存配置初始化一个cacheManager
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.initialCacheNames(cacheNames) // 注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置
.withInitialCacheConfigurations(configMap)
.build();
return cacheManager;
}
}
service层调用展示:
package cn.cache.testcache.shuai;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
/**
* Cacheable注解key需要SpEL表达式书写
*/
@Service
public class CacheService {
@Cacheable(value = "my-redis-cache1",key = "#root.methodName")// 生成的redis中的key名为:"my-redis-cache1::getString"
public String getString(int id){
System.out.println("I am from userService,没有走缓存");
return "成功";
}
}
spring Cache提供了一些供我们使用的SpEL上下文数据,下表直接摘自Spring官方文档:
名称 | 位置 | 描述 | 示例 |
methodName | root对象 | 当前被调用的方法名 | #root.methodname |
method | root对象 | 当前被调用的方法 | #root.method.name |
target | root对象 | 当前被调用的目标对象实例 | #root.target |
targetClass | root对象 | 当前被调用的目标对象的类 | #root.targetClass |
args | root对象 | 当前被调用的方法的参数列表 | #root.args[0] |
caches | root对象 | 当前方法调用使用的缓存列表 | #root.caches[0].name |
Argument Name | 执行上下文 | 当前被调用的方法的参数,如findArtisan(Artisan artisan),可以通过#artsian.id获得参数 | #artsian.id |
result | 执行上下文 | 方法执行后的返回值(仅当方法执行后的判断有效,如 unless cacheEvict的beforeInvocation=false) | #result |
注意:
1.当我们要使用root对象的属性作为key时我们也可以将“#root”省略,因为Spring默认使用的就是root对象的属性。 如
1 | @Cacheable(key = "targetClass + methodName +#p0") |
2.使用方法参数时我们可以直接使用“#参数名”或者“#p参数index”。 如:
1 | @Cacheable(value="users", key="#id") |
1 | @Cacheable(value="users", key="#p0") |
SpEL提供了多种运算符
类型 | 运算符 |
关系 | <,>,<=,>=,==,!=,lt,gt,le,ge,eq,ne |
算术 | +,- ,* ,/,%,^ |
逻辑 | &&,||,!,and,or,not,between,instanceof |
条件 | ?: (ternary),?: (elvis) |
正则表达式 | matches |
其他类型 | ?.,?[…],![…],^[…],$[…] |