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