JSR简介 源码剖析 总结
JSR简介
JSR 全称为 Java Specification Requests
Spring生态从3.1开始支持使用Java Caching(JSR-107)注解来简化开发
介绍Spring提供的概念和注解
简单使用
启动类开启缓存支持
@EnableCaching
public class SpringCacheApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCacheApplication.class, args);
}
}
service 标注@Cacheable
@Cacheable(value = {"employee"}, key = "#id",condition = "#id > 0",unless = "#result == null")
@Override
public Employee findEmployeeById(Integer id) {
return employeeMapper.selectByPrimaryKey(id);
}
其他注解使用
@CachePut(value = {"emp"}, key = "#employee.id")
public Employee updateEmployee(Employee employee) {
employeeMapper.updateByPrimaryKeySelective(employee);
return employee;
}
@CacheEvict(value = {"emp"}, key = "#id")
public void deleteEmployee(Integer id) {
employeeMapper.deleteByPrimaryKey(id);
}
@Service
@CacheConfig(cacheNames = {"emp"})
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeMapper employeeMapper;
@Override
@Cacheable(key = "#id", condition = "#id > 0", unless = "#result == null")
public Employee findEmployeeById(Integer id) {
return employeeMapper.selectByPrimaryKey(id);
}
@Override
@CachePut(key = "#employee.id")
public Employee updateEmployee(Employee employee) {
employeeMapper.updateByPrimaryKeySelective(employee);
return employee;
}
@Override
@CacheEvict(key = "#id")
public void deleteEmployee(Integer id) {
employeeMapper.deleteByPrimaryKey(id);
}
}
源码分析
直接从启动项的 @SpringBootApplication 注解进入,在图中打下断点.
@SpringBootApplication -> @EnableAutoConfiguration -> AutoConfigurationImportSelector.class
双击shift并进入 进入该类中 所有的缓存类型 返回的是所有的缓存组件类及加载顺序
当项目没有额外导入缓存的相关jar时,默认使用的是 SimpleCacheConfiguration 可以随便打开一个缓存组件类,可以看出条件判断注解必须有RedisConnectionFactory.class才能加载Redis缓存组件类 只有SimpleCacheConfiguration才能创建 此时返回的是一个ConcurrentMapCacheManager,进入该类在getCache()处打下断点,debug放行,此时断点不卡住,项目启动完成,接下来发起请求. 首次执行cache为空 加锁并进行二次判断,继续为空,创建ConcurrentMapCache并put到map中,供下次调用是使用 此时进入 Cache 接口的实现类中 -> ConcurrentHashMap 在lookup()出打断点,通过表达式可以看出此时为null 断点继续放在put()上并继续执行,此时到DB中进行了首次查询,并将结果put()到当前缓存中
此时,首次查询结束,清空控制台并再次发起请求 此时可以看到通过’employee’的值取到了缓存,继续执行 再次执行lookup()方法,此时通过key获取到了缓存值,程序放行,直接返回
执行完毕,控制台没有任何sql输出 关于SimpleKey的生成策略,可以查看 SimpleKeyGenerator 类
总结
1.启动时默认使用 SimpleCacheConfiguration 组件类,并创建 ConcurrentMapCacheManager 对象存到容器中 2.底层数据结构为 ConcurrentHashMap 以key,value的形式存放缓存数据 3.整体执行流程: 1)通过指定的名字到CacheManager中获取相应的缓存,首次没有会进行相应的创建 2)去cache中查找缓存,无参数请求时默认的key为new SimpleKey(),单个参数时为该参数值,多个参数时对应调用SimpleKey相应的有参构造 3)没有查到缓存调用目标方法继续执行,从DB中查询数据 4)将数据put到当前缓存中
下篇: Redis缓存使用及加载流程
end
|