springboot版本:2.0.2.RELEASE,1.5.x 同理java
①,pom依赖mysql
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
②,咱们能够观察CacheAutoConfiguration#CacheConfigurationImportSelectorweb
这个静态内部类看出springboot能够让咱们配置哪些缓存,spring
源码以下:sql
static class CacheConfigurationImportSelector implements ImportSelector { @Override public String[] selectImports(AnnotationMetadata importingClassMetadata) { //经过CacheType 获取支持的缓存类型,注意,是有序的从上到下 CacheType[] types = CacheType.values(); String[] imports = new String[types.length]; for (int i = 0; i < types.length; i++) { imports[i] = CacheConfigurations.getConfigurationClass(types[i]); } return imports; } }
能够经过debug=true 查看springboot为咱们加载了哪些类apache
//在主配置类上加上,@EnableCaching,使得缓存注解生效 @EnableCaching @SpringBootApplication public class SpringbootCacheApplication {
@Service public class EmployeeService { @Autowired private EmployeeDao employeeDao; //缓存的key,默认就是传入的id,更多用法请自行百度 @Cacheable(cacheNames = "emp") public Employee findById(Integer id) { System.out.println("查找key为:"+id); return employeeDao.findById(id); } }
@RestController public class EmployeeController { @Autowired private EmployeeService employeeService; @RequestMapping("find/{id}") public Employee findById(@PathVariable("id")Integer id){ return employeeService.findById(id); } }
①,在application.properties 开启debug模式缓存
debug=true
②,经过观察控制台看到只有SimpleCacheConfiguration 是起效了,其他xxCacheConfiguration没有起效springboot
//ConcurrentMapCacheManager配置了 ConcurrentMapCacheManager 做为缓存管理器 @Bean public ConcurrentMapCacheManager cacheManager() { ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager(); List<String> cacheNames = this.cacheProperties.getCacheNames(); if (!cacheNames.isEmpty()) { cacheManager.setCacheNames(cacheNames); } return this.customizerInvoker.customize(cacheManager); } //进入ConcurrentMapCacheManager 类, //这个就是ConcurrentMapCacheManager 获取缓存的方法 @Override @Nullable public Cache getCache(String name) { Cache cache = this.cacheMap.get(name); if (cache == null && this.dynamic) { synchronized (this.cacheMap) { cache = this.cacheMap.get(name); if (cache == null) { //这里建立缓存 cache = createConcurrentMapCache(name); this.cacheMap.put(name, cache); } } } return cache; } //点击createConcurrentMapCache ,能够看到ConcurrentMapCacheManager 建立的cache为ConcurrentMapCache protected Cache createConcurrentMapCache(String name) { SerializationDelegate actualSerialization = (isStoreByValue() ? this.serialization : null); return new ConcurrentMapCache(name, new ConcurrentHashMap<>(256), isAllowNullValues(), actualSerialization); }
①,重点是以下代码mybatis
//经过这行代码,咱们知道SimpleCacheConfiguration是用ConcurrentMap来存储缓存的, //(mybatis的二级缓存也是用map存储的) //因此,咱们能够得出SimpleCacheConfiguration 是内存缓存,至关于memorycache,不会持久化缓存 private final ConcurrentMap<Object, Object> store; //获取缓存 protected Object lookup(Object key) { return this.store.get(key); } //设置缓存 @Override public void put(Object key, @Nullable Object value) { this.store.put(key, toStoreValue(value)); }
第一次访问http://127.0.0.1:8979/find/1 不会走缓存,第二次就走走缓存了app
#第一次访问,打印的日志 2018-05-19 20:09:51.979 INFO 1736 --- [nio-8979-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet' 2018-05-19 20:09:51.979 INFO 1736 --- [nio-8979-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started 2018-05-19 20:09:52.004 INFO 1736 --- [nio-8979-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 25 ms 2018-05-19 20:09:52.012 DEBUG 1736 --- [nio-8979-exec-1] o.s.b.w.s.f.OrderedRequestContextFilter : Bound request context to thread: org.apache.catalina.connector.RequestFacade@20e4d465 查找key为:1 2018-05-19 20:09:56.382 INFO 1736 --- [nio-8979-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2018-05-19 20:09:56.513 INFO 1736 --- [nio-8979-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2018-05-19 20:09:56.517 DEBUG 1736 --- [nio-8979-exec-1] c.c.s.emp.dao.EmployeeDao.findById : ==> Preparing: select * from emp where id=?; 2018-05-19 20:09:56.529 DEBUG 1736 --- [nio-8979-exec-1] c.c.s.emp.dao.EmployeeDao.findById : ==> Parameters: 1(Integer) 2018-05-19 20:09:56.538 DEBUG 1736 --- [nio-8979-exec-1] c.c.s.emp.dao.EmployeeDao.findById : <== Total: 1 #第二次访问,打印的日志 2018-05-19 20:10:49.643 DEBUG 1736 --- [nio-8979-exec-5] o.s.b.w.s.f.OrderedRequestContextFilter : Bound request context to thread: org.apache.catalina.connector.RequestFacade@20e4d465 2018-05-19 20:10:49.645 DEBUG 1736 --- [nio-8979-exec-5] o.s.b.w.s.f.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@20e4d465 2018-05-19 20:10:49.650 DEBUG 1736 --- [nio-8979-exec-8] o.s.b.w.s.f.OrderedRequestContextFilter : Bound request context to thread: org.apache.catalina.connector.RequestFacade@20e4d465 2018-05-19 20:10:49.653 DEBUG 1736 --- [nio-8979-exec-8] o.s.b.w.s.f.OrderedRequestContextFilter : Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@20e4d465