JSR107简介
Java Caching定义了5个核心接口。
- CachingProvider:创建、配置、获取、管理和控制多个CacheManager。
- CacheManager:创建、配置、获取、管理和控制多个唯一命名的Cache。这些Cache存在于CacheManager的上下文中。
- Cache:类似Map的数据结构,存放Key-Value,Cache中有多个Entry。
- Entry:存放一对Key-Value。
- Expiry:设置Entry的有效期,超过有效期Entry将不可用。
JSR结构图
Spring抽象缓存
直接使用JSR实现起来比较复杂,Spring从3.1开始定义了org.springframework.cache.Cache和org.springframework.cache.CacheManager接口来统一不同的缓存技术。
Cache接口
缓存接口,定义缓存操作。Spring提供了Cache接口的各种实现,如RedisCache、EhCacheCache、ConcurrentMapCache等。
CacheManager接口
缓存管理器,管理各种缓存组件(Cache)。
缓存注解
- @Cacheable:主要使用在方法上,被标注的方法在第一次执行后会将获得的数据放入缓存中,第二次调用时候直接从缓存中获取数据,方法不再执行。
- @CacheEvict:一般用在delete方法上,数据被删除后,将缓存中的数据一起清空。
- @CachePut:一般用在update方法上,保证方法每次都会执行,并且将结果更新到缓存中。
- @EnableCaching:使用在springboot的主配置类上,开启基于注解的缓存模式。
缓存注解详解
@Cacheable
//@Cacheable的源码
public @interface Cacheable {
@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};
String key() default "";
String keyGenerator() default "";
String cacheManager() default "";
String cacheResolver() default "";
String condition() default "";
String unless() default "";
boolean sync() default false;
}
- cacheNames/value:指定缓存的名字。
- key:指定缓存数据的key,可以使用SpEl表达式。如果不指定,默认将方法参数的值作为key。
- keyGenerator:key的生成器(key与keyGenerator二选一进行使用)。
- cacheManager:指定缓存管理器。
- cacheResolver:指定缓存解析器(cacheManager与cacheResolver二选一进行使用)。
- condition:指定条件,符合条件的情况下才缓存。可以使用SpEl表达式。
- unless:指定条件,符合条件的情况下不缓存。可以使用SpEl表达式。
- sync:指定缓存是否使用异步模式。
在springboot项目中使用spring缓存抽象
pom文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
主配置类
@SpringBootApplication
@MapperScan("com.leo.cache.mapper")
@EnableCaching
public class SpringbootCacheApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootCacheApplication.class, args);
}
}
实体类
public class User {
private Integer id;
private String userName;
private String passWord;
private String realName;
//这里省略掉get与set方法
}
对应的数据库表这里就不放上来了。
Mapper层
public interface UserMapper {
@Select("select * from user")
List<User> selectUserAll();
}
这里直接使用注解的方式写sql语句
Service层
@Service
public class UserService {
@Autowired
private UserMapper mapper;
@Cacheable(cacheNames = "user" , key="1")
public List<User> findUserAll(){
System.out.println("查询所有学生");
return mapper.selectUserAll();
}
}
这里将@Cacheable标注在Service层的方法上,其实放在Controller层或者Mapper层也是可以的。
Controller层
@RestController
public class UserController {
@Autowired
private UserService service;
@GetMapping("/users")
public List<User> getUsers(){
return service.findUserAll();
}
}
运行结果
第一次访问http://localhost:8080//users
后续访问控制台不再输出“查询所有学生”。