SpringBoot Cache初体验
一、JSR107 缓存规范
Java Caching定义了5个核心接口,分别是CachingProvider, CacheManager, Cache, Entry 和 Expiry。
- CachingProvider:定义了创建、配置、获取、管理和控制多个
CacheManager
。一个应用可以在运行期访问多个CachingProvider
。 - CacheManager:定义了创建、配置、获取、管理和控制多个唯一命名的
Cache
,这些Cache
存在于CacheManager
的上下文中。一个CacheManager
仅被一个CachingProvider
所拥有。 - Cache:是一个类似Map的数据结构并临时存储以Key为索引的值。一个
Cache
仅被一个CacheManager
所拥有。 - Entry:是一个存储在
Cache
中的key-value对。 - Expiry:每一个存储在
Cache
中的条目有一个定义的有效期。一旦超过这个时间,条目为过期的状态。一旦过期,条目将不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。
二、Spring缓存抽象
Spring从3.1开始定义了org.springframework.cache.Cache
和org.springframework.cache.CacheManager
接口来统一不同的缓存技术;并支持使用JCache(JSR-107)
注解简化我们开发;
Cache
接口为缓存的组件规范定义,包含缓存的各种操作集合;Cache
接口下Spring提供了各种xxxCache的实现;如RedisCache
,EhCacheCache
,ConcurrentMapCache
等;
每次调用需要缓存功能的方法时,Spring会检查指定参数的指定的目标方法是否已经被调用过;如果有就直接从缓存中获取方法调用后的结果,如果没有就调用方法并缓存结果后返回给用户。下次调用直接从缓存中获取。
使用Spring缓存抽象时我们需要关注以下两点:
- 确定方法需要被缓存以及他们的缓存策略
- 从缓存中读取之前缓存存储的数据
三、重要概念&缓存注解
Cache | 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等 |
---|---|
CacheManager | 缓存管理器,管理各种缓存(Cache )组件 |
@Cacheable | 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存 |
@CacheEvict | 清空缓存 |
@CachePut | 保证方法被调用,又希望结果被缓存。 |
@EnableCaching | 开启基于注解的缓存 |
keyGenerator | 缓存数据时key生成策略 |
serialize | 缓存数据时value序列化策略 |
@Cacheable/@CachePut/@CacheEvict主要的参数
Cache SpEL available metadata
四、缓存使用
- 引入spring-boot-starter-cache模块
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
- @EnableCaching开启缓存
@MapperScan("club.lylgjiang.cache.mapper")
@EnableCaching
@SpringBootApplication
public class SpringBootAdvancedApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootAdvancedApplication.class, args);
}
}
- 使用缓存注解
// Mapper层
public interface EmployeeMapper {
@Select("SELECT * FROM employee WHERE id=#{id}")
public Employee selectEmpById(Integer id);
}
// Service层
@Service
public class EmployeeService {
@Autowired
EmployeeMapper employeeMapper;
// 添加缓存注解
@Cacheable("employee")
public Employee getEmpById(Integer id) {
return employeeMapper.selectEmpById(id);
}
}
// Controller层
@RestController
public class EmpController {
@Autowired
EmployeeService employeeService;
@GetMapping("/emp/{id}")
public Employee showEmployee(@PathVariable Integer id) {
return employeeService.getEmpById(id);
}
}
其他设置:
// 设置项目端口为80
server.port=80
// 设置springboot的club.lylgjiang.cache(mapper层在此包中)包下日志级别为debug
logging.level.club.lylgjiang.cache=debug
验证:
在浏览器中输入http://localhost/emp/3
其中浏览器显示数据与控制台输出数据如下图所示:
- 刷新浏览器(F5):控制台无变化,证明无响应的SQL语句执行,缓存成功。