JSR107缓存规范
- CacheingProvider 定义了创建 配置 获取 管理和控制多个CacheManager.一个应用可以在运行期访问多个CachingProvicer
- CacheManager定义了创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。
- Cache是一个类似Map的数据结构并临时存储以Key为索引的值。一个Cache仅被一个CacheManager所拥有
- Entry是一个存储在Cache中的key-value对。
- Expiry每一个存储在Cache中的条目有一个定义的有效期。一旦超过这个时间,条目为过期的状态。一旦过期,条目将不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。
通常更常用的是Spring缓存抽象
Spring缓存抽象
org.springframework.cache.Cache
org.springframework.cache.CacheManager
这两个接口来统一不同的缓存技术;并支持使用JCache(JSR-107)注解简化开发
Cache | 缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等 |
CacheManager | 缓存管理器,管理各种缓存(Cache)组件 |
@Cacheable | 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存 |
@CacheEvict | 清空缓存 |
@CachePut | 保证方法被调用,又希望结果被缓存。 |
@EnableCaching | 开启基于注解的缓存 |
keyGenerator | 缓存数据时key生成策 |
serialize | 缓存数据时value序列化策略 |
SpringCache
Spring boot默认使用的是SimpleCacheConfiguration,即使用ConcurrentMapCacheManager来实现缓存。
缓存的使用
-
导入场景启动器
<!--缓存--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId> spring-boot-starter-cache </artifactId> </dependency>
-
开启Spring注解
/** * 开启基于注解的缓存 * @CacheEvict * @CacePut * @Cacheable //缓存 */ @EnableCaching @MapperScan("com.springboot.cache.dao") @SpringBootApplication public class SpringBootCacheApplication { public static void main(String[] args) { SpringApplication.run(SpringBootCacheApplication.class, args); } }
-
使用注解
@Service /** *@CacheConfig配置的是一个公共配置,可以不配置 *在使用时具体配置 **/ @CacheConfig(cacheNames="userCache") public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public List<User> findAll() { return userDao.findAll(); } /** * 运行流程: * @Cacheable: * 1、方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的名字获取; * (CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建。 * 2、去Cache中查找缓存的内容,使用一个key,默认就是方法的参数; * key是按照某种策略生成的;默认是使用keyGenerator生成的,默认使用SimpleKeyGenerator生成key; * 3、没有查到缓存就调用目标方法; * 4、将目标方法返回的结果,放进缓存中 * * @Cacheable标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存, * 如果没有就运行方法并将结果放入缓存;以后再来调用就可以直接使用缓存中的数据; * 几个属性: * cacheNames/value:指定缓存组件的名字;,是数组的方式,可以指定多个缓存; * * key:缓存数据使用的key;可以用它来指定。默认是使用方法参数的值 1-方法的返回值 * 编写SpEL; #i d;参数id的值 #a0 #p0 #root.args[0] * getEmp[2] * * keyGenerator:key的生成器;可以自己指定key的生成器的组件id * key/keyGenerator:二选一使用; * * cacheManager:指定缓存管理器; * * condition:指定符合条件的情况下才缓存; * ,condition = "#id>0" * condition = "#a0>1":第一个参数的值》1的时候才进行缓存 * * unless:否定缓存;当unless指定的条件为true,方法的返回值就不会被缓存;可以获取到结果进行判断 * unless = "#result == null" * unless = "#a0==2":如果第一个参数的值是2,结果不缓存; * sync:是否使用异步模式 * */ @Override @Cacheable(key = "#userId") public User findByUserId(Integer userId) { return userDao.findByUserId(userId); } /** * @CachePut:既调用方法,又更新缓存数据;同步更新缓存 * 修改了数据库的某个数据,同时更新缓存; * 运行时机: * 1、先调用目标方法 * 2、将目标方法的结果缓存起来 * *必须要有返回值 不然更新后的缓存会为null * 更新和新建时的 value和key要一致 */ @Override @CachePut(key = "#user.userId") public User Update(User user) { userDao.update(user); return user; } @Override public User save(User user) { userDao.save(user); return user; } /** * @CacheEvict:缓存清除 * key:指定要清除的数据 * allEntries = true:指定清除这个缓存中所有的数据 * beforeInvocation = false:缓存的清除是否在方法之前执行 * 默认代表缓存清除操作是在方法执行之后执行;如果出现异常缓存就不会清除 * beforeInvocation = true: * 代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除 */ @Override @CacheEvict(key = "#userId") public void delete(Integer userId) { userDao.delete(userId); } }